關乎mysql資料庫的連線查詢和子查詢的效率問題
前言:正常情況下,連線查詢是比子查詢效率要高的,因為子查詢需要建立臨時表。但是,在實際測試中,有部分情況子查詢效率會比連線查詢要高
1:去重的情況下
①連線查詢
SELECT
DISTINCT itm.team_id
FROM
表1 itm
LEFT JOIN 表2 itmc on itm.team_id=itmc.team_id
WHERE
itmc.up_start = !1
AND itmc.check_state = !1
AND itm.NAME LIKE CONCAT( '', '張', '%' )
下面是查詢結果:
使用explian檢視語句,發現都使用了索引,是我們想要的效果(使用索引)
②使用子查詢
SELECT
DISTINCT itm.team_id
FROM
表1 itm ,
(select DISTINCT itmg.team_id from 表2 itmg where itmg.up_start != 1 AND itmg.check_state != 1) tab_a
where
itm.team_id = tab_a.team_id
and itm.NAME LIKE '張%'
下面是查詢結果
使用explian檢視語句,發現主表和副表也都使用了索引
測試總結:
1:查詢的結果是一致的,如果沒有加去重的話,兩個sql語句,連線查詢效率相對高一些
2:現在兩個查詢語句都使用了去重,連線查詢效率卻比子查詢效率低得多
分析:個人認為這是由於去重的原因,連線查詢去重機制是將兩張表中符合條件的資料先篩選出來,然後再去重;但是子查詢相當於去重了兩遍,副表中篩選了一次以後,資料量小了很多,這時候再去跟主表中的資料匹配,再去重,工作量小了很多, 所以查詢效率高了很多
總結:
1:在正常情況下,我還是堅持認為連線查詢較好,子查詢首先可讀性就比較差,維護成本比較高,同時子查詢也會建立臨時表浪費資源
2:像上面的那種情況確實給我們啟示,某些特殊情況下,子查詢確實有用武之地,也不應該一味排斥
3:像上面的那種查詢需求,其實在設計之初如果能夠考慮到這種應用場景的話,不至於像現在這樣難辦,所以表設計還是核心
關於子查詢的小拓展:
1:子查詢可以放在很多地方,比如select,from,where後面,但是不能放在group by後
2:如果放在select後面,會造成多次執行子查詢語句,外查詢每次執行一次,都會執行一次子查詢(不知道我理解的對不對,希望有同學能夠指正我的錯誤!)