文章出處
文章列表
前置說明:
本文旨在通過一個簡單的執行計劃來引申并總結一些SQL Server數據庫中的SQL優化的關鍵點,日常總結,其中的概念介紹中有不足之處有待補充修改,希望大神勘誤。
SQL語句如下:
SELECT <所需列> --列太多,不一一列出
FROM study1
INNER JOIN series1
ON (study1.study_uid_id = series1.study_uid_id) --連接條件1
INNER JOIN image1 image1
ON (series1.series_uid_id = image1.series_uid_id) --連接條件2
where ((study1.user_group &8) != 0) --過濾條件1
and (series1.modality) not in ('PR', 'KO', 'SR', 'AU') --過濾條件2
and study1.study_uid ='xxx' --過濾條件3
order by <排序列>; --列太多,不一一列出
第一部分:執行計劃怎么看?
1.從右往左看 + 從上往下看
同一行的執行計劃步驟,右邊的先執行。同一列的執行步驟,上邊的先執行。
SQL Server優化器根據統計信息生成執行計劃,由返回行數和統計信息直方圖決定執行的先后順序和表連接方式,但是最基本的一點:過濾條件先于與連接條件執行還是要遵守的。
表連接方式包含nested loop,merge join,hash join這三種,三種連接方式的區別有興趣可以bing搜索查看,與Oracle的三種表連接方式一樣,這里不再詳述。
步驟一:根據統計信息發現3個where條件中【過濾條件3】的選擇性最好,預估行數最少,于是放在執行計劃最右。由于study_uid是主鍵,無需回表(即無需書簽查找),因此實際上步驟一的聚集索引查找同時還兼顧了【((study1.user_group &8) != 0)】這個【過濾條件2】。
步驟一對應過濾條件1、3。
步驟二:這個index seek是根據步驟一得到的study_uid_id結合【連接條件1】,對series_index進行的索引查找,series_index是series表的study_uid_id這列的索引。
步驟三:步驟一和步驟二通過【連接條件1】進行nested loop合成一個中間表,這個中間表中有從series_index中拿到的series表的主鍵值,有了這個主鍵值我們就可以在步驟四中進行針對series的主鍵鍵查找。
步驟三對應連接條件1。
步驟四:這一步的目的就是通過步驟三得到的series表主鍵值,到series的聚集索引中找到主鍵對應的完整的行,在完整行記錄中找到對應【過濾條件2】的行記錄。
步驟四對應過濾條件2。
步驟五:步驟三、四通過nested loop合成一個中間表,這里的nested loop并不對應某個連接條件,只是純粹的為了生成一個中間表。
步驟六:根據步驟五中間表里的series_uid_id值到image1表中進行索引查找,image_index就是image1.series_uid_id列的索引。
步驟七:步驟五、六進行nested loop生成中間表,這個中間表中含有image1表的主鍵值,這個主鍵值是執行步驟六時從image_index中拿到的。拿到這主鍵值我們就可以在步驟八中去取到最終我們需要的所有image1表的列了。
步驟七對應連接條件2。
步驟八:根據步驟七中間表中的image1主鍵值,到image1的主鍵聚集索引中去取我們需要的image1的列數據。
步驟九:步驟七、八進行nested loop生成最后的中間表。
步驟十:對步驟九中生成的中間表進行排序。
最終,我們就取到了需要的、排序好的所有數據。
2.查看每一步的詳細信息
在出現錯誤的執行計劃時,有時我們需要判斷為什么優化器選錯了執行計劃,由于選錯執行計劃很有可能導致SQL語句變慢,因此搞清其中的原因是很有必要的。
將鼠標移到每一個執行計劃node,會出現如下圖所示的詳細信息。

我們需要關注的主要有以下幾點:
- 物理運算和邏輯運算:
一.表連接的物理運算方式:
1.嵌套循環
Logical Operation:nested loop
2.哈希連接
Logical Operation:hash join
3.合并連接
Logical Operation:merge join
二.索引訪問的物理運算方式:
1.索引掃描
Logical Operation:index scan
2.索引查找
Logical Operation:index seek
3.聚集索引掃描
Logical Operation:cluster index scan
4.聚集索引查找
Logical Operation:cluster index seek
三.表訪問的物理運算方式:
1.表掃描
Logical Operation:table scan
2.RID查找
Logical Operation:RID lookup
3.鍵查找
Logical Operation:key lookup。
(以前的bookmark lookup在SQL Server 2005之后被細分為RID lookup和key loopkup)
##關于RID LOOKUP和KEY LOOKUP的區別,一個是無主鍵一個是有主鍵時候出現的,RID LOOKUP的效率不如KEY LOOKUP,因此微軟警告表一定要有主鍵##
四.其他的物理運算方式:
1.排序
Logical Operation:sort
2.流聚合和哈希匹配
Logical Operation:Aggregate。
在相應排序的流中,計算多組行的匯總值。group by子句出現時出現,一般配合min,max,avg,count,sum等組函數。哈希匹配適用于排序量較大時,優化器總是選擇流聚合和哈希匹配兩種物理運算中代價較小的一種。
3.計算標量
Logical Operation:Compute scalar,count(),avg(),sum()等計算組函數出現時出現,一般出現在流聚合物理運算之后,哈希匹配自帶計算標量功能。
4.并行
Logical Operation:Parallel,與并行開銷閾值和預估的執行時間有關。
- 估計行數
- 謂詞(或seek 謂詞,有時兩者一起出現)
第二部分:怎么優化?
SQL Server的優化還是相對簡單的,大致分為以下幾種:
1.統計信息失真引起的
更新統計信息即可。
2.索引缺失或者索引過多或索引錯誤引起的
增刪索引,或者更改聯合索引順序或者加包含列即可。
3.語句太爛引起的
具體情況具體改寫吧......幺蛾子太多列不出來了。
文章列表
全站熱搜