文章出處

前置說明:
本文旨在通過一個簡單的執行計劃來引申并總結一些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,會出現如下圖所示的詳細信息。
我們需要關注的主要有以下幾點:
  • 物理運算和邏輯運算
        邏輯運算表明了本步驟執行計劃做了什么,而物理運算表明用哪種方式做的。一般物理運算和邏輯運算名字相同,也有例外如Aggregate這種邏輯運算就包含流聚合和哈希匹配兩種物理實現方式。
    一.表連接的物理運算方式
        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語句的過濾條件或內部過濾條件。
 
第二部分:怎么優化?
SQL Server的優化還是相對簡單的,大致分為以下幾種:
1.統計信息失真引起的
更新統計信息即可。
2.索引缺失或者索引過多或索引錯誤引起的
增刪索引,或者更改聯合索引順序或者加包含列即可。
3.語句太爛引起的
具體情況具體改寫吧......幺蛾子太多列不出來了。

 

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()