首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 使用者變數實現「短路 UNION」:找到即停止,避免全表掃描

     編輯:MySQL 資料庫相關知識

    問題背景

    需求:優先從 users 找用戶,找到即返回;找不到再去 users_archived 找。普通 UNION ALL 會掃描兩表並可能產生重複行。

    普通寫法 (全掃描、可重複)

    SELECT id FROM users WHERE id = 123456
    UNION ALL
    SELECT id FROM users_archived WHERE id = 123456;

    短路寫法 (用戶變數 @found)

    SELECT GREATEST(@found := -1, id) AS id, 'users' AS which_tbl
    FROM users WHERE id = 1
    UNION ALL
    SELECT id, 'users_archived'
    FROM users_archived WHERE id = 1 AND @found IS NULL
    UNION ALL
    SELECT 1, 'reset' FROM DUAL WHERE (@found := NULL) IS NOT NULL;

    執行邏輯逐行拆解

    1. 第一分支:@found := -1 賦值為非 NULL,GREATEST(-1, id) 返回 id (正數)。若找到行,輸出該行,@found 變為 -1 (非 NULL)。
    2. 第二分支:WHERE ... AND @found IS NULL。若第一分支找到,@found 非 NULL,條件失效,**完全不掃描** users_archived。
    3. 第三分支:(@found := NULL) IS NOT NULL 永假 (NULL IS NOT NULL = FALSE),不產出行,**僅執行賦值重置** @found 為 NULL,不影響後續查詢。

    關鍵技巧總結

    • GREATEST(@var := val, col):在 SELECT 列表中完成「賦值 + 取值」原子操作,不輸出額外欄位
    • @var IS NULL 作為守衛條件,實現短路
    • DUAL 虛擬表配合永假條件完成變數重置,無副作用
    • 第二欄 which_tbl 標識資料來源,方便應用層判斷

    適用場景

    • 多級快取/分層存儲查詢 (熱表→冷表→備份表)
    • 優先級配置查找 (用戶級→組織級→系統級預設)
    • 任何「找到即停」的 UNION 場景
    1. 上一篇文章:
    2. 下一篇文章:
    Copyright © 程式碼之家 All Rights Reserved