需求:查詢admin表除前3條(按userid排序)以外的所有數據。初始寫法:
SELECT * FROM admin
WHERE userid NOT IN (SELECT userid FROM admin ORDER BY userid LIMIT 3)
ORDER BY userid DESC;
報錯:This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'。且NOT IN子查詢在大數據量下性能極差(無法使用索引、NULL值導致邏輯錯誤)。
CREATE VIEW view_top3_admin AS
SELECT * FROM admin ORDER BY userid LIMIT 3;
SELECT * FROM admin a
WHERE NOT EXISTS (
SELECT 1 FROM view_top3_admin b WHERE b.userid = a.userid
)
ORDER BY a.userid DESC;
原理解析:SELECT 1不讀取實際列數據,僅判斷存在性;NOT EXISTS可利用索引,且正確處理NULL值。視圖將LIMIT下推,繞過子查詢限制。
| 特性 | UNION | UNION ALL |
|---|---|---|
| 去重 | 是(排序+唯一) | 否(直接合併) |
| 性能 | 較慢 | 極快 |
| 適用場景 | 結果集可能重複 | 確認無重複或允許重複 |
黃金法則:能用UNION ALL絕不使用UNION。報表查詢、日誌合併、分表查詢聚合均優先選擇UNION ALL,必要時應用層去重。