-- 查詢最新商品 SELECT goods_id, goods_name FROM goods WHERE goods_id = (SELECT MAX(goods_id) FROM goods); -- 各分類最新商品 SELECT cat_id, goods_id, goods_name FROM goods WHERE goods_id IN (SELECT MAX(goods_id) FROM goods GROUP BY cat_id);
-- 平均分:掛科≥2門的學生
SELECT name, AVG(score) FROM stu
WHERE name IN (
SELECT name FROM (
SELECT name, COUNT(*) AS gk FROM stu
WHERE score < 60 GROUP BY name HAVING gk >= 2
) AS t
) GROUP BY name;
-- 有商品的分類 SELECT cat_id, cat_name FROM category WHERE EXISTS (SELECT 1 FROM goods WHERE goods.cat_id = category.cat_id);
基於 EXPLAIN EXTENDED 實測數據(表 t1、t2 均有索引):
| 子查詢類型 | 優化策略 | 執行計劃特徵 | 版本支持 |
|---|---|---|---|
| EXISTS | 無優化,保持 Dependent Subquery | select_type=DEPENDENT SUBQUERY | 全版本 |
| NOT EXISTS | 無優化,保持 Dependent Subquery | select_type=DEPENDENT SUBQUERY | 全版本 |
| IN (非相關) | 半連接 + 物化 | select_type=MATERIALIZED, SIMPLE + semi join | 5.6.5+ |
| NOT IN (非相關) | 物化優化,不消除子查詢 | select_type=SUBQUERY + <materialize> | 5.6+ |
| >ALL / <ALL | 轉換為 MAX/MIN 聚合 | select_type=SUBQUERY + <max>/<min> | 全版本 |
| =ALL | EXISTS 策略優化 | 含 <exists> 標記 | 全版本 |
| >SOME / <SOME | 轉換為 MIN/MAX 聚合 | select_type=SUBQUERY + min/max | 全版本 |
| =SOME | 等價 IN,半連接物化 | select_type=MATERIALIZED + semi join | 5.6.5+ |
| >ANY / <ANY | 同 SOME,轉 MIN/MAX | select_type=SUBQUERY + min/max | 全版本 |
| =ANY | 等價 IN,半連接物化 | select_type=MATERIALIZED + semi join | 5.6.5+ |
將子查詢「上拉」到外層查詢,轉換為類似 JOIN 的執行計劃,避免重複掃描。適用於 IN、=ANY、=SOME 非相關子查詢。EXPLAIN 中出現 semi join 標識。
將子查詢結果集寫入臨時表(內存/磁盤),建立哈希索引,外層查詢通過索引查找。適用於 IN、NOT IN 非相關子查詢。EXPLAIN 中 select_type=MATERIALIZED。
針對 >ALL、<ALL、>SOME、<SOME、>ANY、<ANY,若子查詢列有唯一索引,優化器直接走索引求極值,子查詢僅執行一次。
SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t1.id=t2.id)SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NOT NULL-- 查看優化器重寫後的 SQL EXPLAIN EXTENDED SELECT ...; SHOW WARNINGS; -- 強制指定優化策略 SELECT /*+ MAX_EXECUTION_TIME(1000) */ ...; SELECT /*+ NO_SEMIJOIN(t2) */ ...;