對比SQL中簡單巢狀查詢與非巢狀查詢的異同
GPS平臺、網站建設、軟體開發、系統運維,找森大網路科技!
https://cnsendnet.taobao.com
來自森大科技官方部落格
http://www.cnsendblog.com/index.php/?p=2159
本文將討論的是SQL中簡單巢狀查詢與非巢狀查詢的異同,通過這些來更加深刻理解SQL語句。
某天的工作是修復某個專案的bug,接著就發現,其sql極其混亂,有非常多的left join和in操作,還有巢狀查詢(只有一個表的巢狀查詢)。不知道看到過哪裡的資料說,巢狀查詢速度慢,於是我把全部巢狀查詢都改成join的形式,巢狀查詢裡面的where條件,我都寫到join...on後面去了。突然一個想法冒出來:篩選條件跟在join...on後面 和 跟在整個sql語句最後面的where後面有什麼區別呢?還有巢狀查詢真的慢麼?於是便有下面的測試產生,資料庫環境為MS SQL 2005。
一,inner join
先看看非巢狀查詢:
- a.select*fromt1
- innerjoint2ont1.id=t2.id
- innerjoint3ont1.id=t3.id
- wheret1.a=1andt2.b=1andt3.c=1
- b.select*fromt1
- innerjoint2ont1.id=t2.idandt2.b=1
- innerjoint3ont1.id=t3.id
- wheret1.a=1andt3.c=1
- 10.
11. c.select*fromt1
12. innerjoint2ont1.id=t2.idandt2.b=1
13. innerjoint3ont1.id=t3.idandt3.c=1
14. wheret1.a=1
在上面三個非巢狀查詢,讓“and t2.b=1”和“and t3.c=1”分別在join...on和where之間遊走,用Management Studio選中“包含實際的執行計劃”並執行這三條語句,都得出下面這個執行計劃。
三個“聚集索引掃描”的謂詞從上到下分別是:
1.t3.c=1
2.t1.a=1 (seek謂詞:t1.id=t3.id)
3.t2.b=1(seek謂詞:t2.id=t3.id)
故可以認為:在MS SQL2005中,條件跟在join...on後面和 跟在where後面是等價的。
接著看巢狀查詢:
- d.select*fromt1
- inner
- innerjoint3ont1.id=t3.id
- wheret1.a=1andt3.c=1
- e.select*fromt1
- innerjoin(select*fromt2wheret2.b=1)aont1.id=a.id
- innerjoin(select*fromt3wheret3.c=1)bont1.id=b.id
- wheret1.a=1
- 10.
11. f.elect*fromt1
12. innerjoin(selectt3.id,t2.b,t3.cfromt3innerjoint2ont2.id=t3.idwheret2.b=1andt3.c=1)aont1.id=a.id
13. wheret1.a=1
第一句sql語句把t2的查詢變成子查詢,第二句sql語句把t2,t3分別變成子查詢,第三句把t2和t3的查詢合成一個子查詢,再看看實際的執行計劃:
跟上面非巢狀查詢的執行計劃一模一樣。
故可以認為:簡單(注意是簡單的,複雜的情況得另外考慮)巢狀查詢和其相對應的非巢狀查詢形式,執行效率是一樣的(網上一些文章指出這是MS SQL優化器針對這些巢狀查詢進行了優化)。
接著,在上面兩個執行計劃的圖中又發現一個小問題,為什麼明明是select t1 inner join t2 inner join t3,執行計劃卻把t1和t3先inner join(t1.id = t3.id)再跟t2 inner join(t2.id = t3.id)起來?
經過三個表,四個表,五個表進行連線測試,發現這些順序都是不確定的。很可能這些順序是根據SQL優化器內的演算法所決定的,由於沒有原始碼,所以無從考究。
(感謝Keep Walking的補充:
“可以指定順序,force order選項,和keep plan選項
數量級,索引,統計的不同都可以導致順序變化”。
我Google了一下option force order和option keep plan,發現SQL優化器做了很多事情,在這文章就不列出來了,大家有興趣可以Goo一下。)
PS:
1.經測試,在join on後面t1.id = t2.id與t2.id = t1.id等價
GPS平臺、網站建設、軟體開發、系統運維,找森大網路科技!
https://cnsendnet.taobao.com
來自森大科技官方部落格
http://www.cnsendblog.com/index.php/?p=2159