(轉)MSSQLSERVER執行計劃詳解

         原文地址:http://www.cnblogs.com/knowledgesea/p/5005163.htmlhtml

序言

本篇主要目的有二:算法

一、看懂t-sql的執行計劃,明白執行計劃中的一些常識。sql

二、可以分析執行計劃,找到優化sql性能的思路或方案。數據庫

若是你對sql查詢優化的理解或常識不是很深刻,那麼推薦幾騙博文給你:SqlServer性能檢測和優化工具使用詳細 ,sql語句的優化分析T-sql語句查詢執行順序緩存

執行計劃簡介

一、什麼是執行計劃?數據結構

大哥提交的sql語句,數據庫查詢優化器,通過分析生成多個數據庫能夠識別的高效執行查詢方式。而後優化器會在衆多執行計劃中找出一個資源使用最少,而不是最快的執行方案,給你展現出來,能夠是xml格式,文本格式,也能夠是圖形化的執行方案。工具

二、預估執行計劃,實際執行計劃oop

選擇語句,點擊上面其中一個執行計劃,預估執行計劃能夠當即顯示,而實際執行計劃則須要執行sql語句後出現。預估執行計劃不等於實際執行計劃,可是絕大多數狀況下實際的執行計劃跟預估執行計劃都是一致的。統計信息變動或者執行計劃重編譯等狀況下,會形成不一樣。性能

三、爲何要讀懂執行計劃優化

首先執行計劃讓你知道你複雜的sql究竟是怎麼執行的,有沒有按照你想的方案執行,有沒有按照最高效的方式執行,使用啦衆多索引的哪個,怎麼排序,怎麼合併數據的,有沒有形成沒必要要資源浪費等等。官方數據顯示,執行t-sql存在問題,80%均可以在執行計劃中找到答案。

四、針對圖形化執行計劃分析

執行計劃,能夠以文本,xml,圖形化展現出來。本騙主要以圖形化執行計劃主導進行分析,然而執行計劃中包含78個可用的操做符,本篇也只能對經常使用的進行分析,經常使用的幾乎就包含你平常全部的了。Msdn上有圖片介紹:https://msdn.microsoft.com/zh-cn/library/ms175913(v=sql.90).aspx

五、怎麼看執行計劃

圖形化執行計劃是從上到下從又到左看的。

六、清除緩存的執行計劃

dbcc freeprocache

dbcc flushprocindb(db_id)

看懂圖形化執行計劃

一、連線

一、越粗表示掃描影響的行數愈多。

二、Actual Number of Rows  掃描中實際影響的的行數。

三、Estimated Number of Rows 預估掃描影響的行數。

四、Estimated row size 操做符生成的行的估計大小(字節)。

五、Estimated Data Size 預估影響的數據的大小。

二、Tooltips,當前步驟執行信息

  

Note:這個tips的信息告訴咱們執行的對象是什麼,採用的操做操做是什麼,查找的數據是什麼,使用的索引是什麼,排序與否,預估cpu、I/O、影響行數,實際行數等信息。具體參數清單參見msdn:https://msdn.microsoft.com/zh-cn/library/ms178071(v=sql.90).aspx

三、Table Scan(表掃描)

當表中沒有彙集索引,又沒有合適索引的狀況下,會出現這個操做。這個操做是很耗性能的,他的出現也意味着優化器要遍歷整張表去查找你所須要的數據。

四、Clustered Index Scan(彙集索引掃描)、Index Scan(非彙集索引掃描)

 

這個圖標兩個操做均可以使用,一個彙集索引掃描,一個是非彙集索引掃描。

彙集索引掃描:彙集索引的數據體積實際是就是表自己,也就是說表有多少行多少列,彙集全部就有多少行多少列,那麼彙集索引掃描就跟表掃描差很少,也要進行全表掃描,遍歷全部表數據,查找出你想要的數據。

非彙集索引掃描:非彙集索引的體積是根據你的索引建立狀況而定的,能夠只包含你要查詢的列。那麼進行非彙集索引掃描,即是你非彙集中包含的列的全部行進行遍歷,查找出你想要的數據。

五、Key Lookup(鍵值查找)

首先須要說的是查找,查找與掃描在性能上徹底不是一個級別的,掃描須要遍歷整張表,而查找只須要經過鍵值直接提取數據,返回結果,性能要好。

當你查找的列沒有徹底被非彙集索引包含,就須要使用鍵值查找在彙集索引上查找非彙集索引不包含的列。

六、RID Lookoup(RID查找)

 

跟鍵值查找相似,只不過RID查找,是須要查找的列沒有徹底被非彙集索引包含,而剩餘的列所在的表又不存在彙集索引,不能鍵值查找,只能根據行表示Rid來查詢數據。

七、Clustered Index Seek(彙集索引查找)、Index Seek(非彙集索引查找)

彙集索引查找和非彙集索引查找都是使用該圖標。

彙集索引查找:彙集索引包含整個表的數據,也就是在彙集索引的數據上根據鍵值取數據。

非彙集索引查找:非彙集索引包含建立索引時所包含列的數據,在這些非彙集索引的數據上根據鍵值取數據。

八、Hash Match

 

這個圖標有兩種地方用到,一種是表關聯,一種是數據聚合運算時。

再分別說這兩中運算的前面,我先說說Hashing(編碼技術)和Hash Table(數據結構)。

Hashing:在數據庫中根據每一行的數據內容,轉換成惟一符號格式,存放到臨時哈希表中,當須要原始數據時,能夠給還原回來。相似加密解密技術,可是他能更有效的支持數據查詢。

Hash Table:經過hashing處理,把數據以key/value的形式存儲在表格中,在數據庫中他被放在tempdb中。

接下來,來講說Hash Math的表關聯跟行數據聚合是怎麼操做運算的。

表關聯:

如上圖,關聯兩個數據集時,Hash Match會把其中較小的數據集,經過Hashing運算放入HashTable中,而後一行一行的遍歷較大的數據集與HashTable進行相應的匹配拉取數據。

數據聚合:當查詢中須要進行Count/Sum/Avg/Max/Min時,數據可能會採用把數據先放在內存中的HashTable中而後進行運算。

九、Nested Loops

這個操做符號,把兩個不一樣列的數據集彙總到一張表中。提示信息中的Output List中有兩個數據集,下面的數據集(inner set)會一一掃描與上面的數據集(out set),知道掃描完爲止,這個操做纔算是完成。

十、Merge Join

這種關聯算法是對兩個已經排過序的集合進行合併。若是兩個聚合是無序的則將先給集合排序再進行一一合併,因爲是排過序的集合,左右兩個集合自上而下合併效率是至關快的。

十一、Sort(排序)

對數據集合進行排序,須要注意的是,有些數據集合在索引掃描後是自帶排序的。

十二、Filter(篩選)

根據出如今having以後的操做運算符,進行篩選

1三、Computer Scalar

 

在須要查詢的列中須要自定義列,好比count(*) as cnt ,select name+''+age 等會出現此符號。

根據執行計劃細節要作的優化操做

這裏會有不少建議給出,我不一一舉例了,給出幾個示例,想作到優化行家,多的還須要你們去悟去理解。

一、若是select * 一般狀況下彙集索引會比非彙集索引更優。

二、若是出現Nested Loops,須要查下是否須要彙集索引,非彙集索引是否能夠包含全部須要的列。

三、Hash Match鏈接操做更適合於須要作Hashing算法集合很小的鏈接。

四、Merge Join時須要檢查下原有的集合是否已經有排序,若是沒有排序,使用索引可否解決。

五、出現表掃描,彙集索引掃描,非彙集索引掃描時,考慮語句是否能夠加where限制,select * 是否能夠去除沒必要要的列。

六、出現Rid查找時,是否能夠加索引優化解決。

七、在計劃中看到不是你想要的索引時,看可否在語句中強制使用你想用的索引解決問題,強制使用索引的辦法Select CluName1,CluName2 from Table with(index=IndexName)。

八、看到不是你想要的鏈接算法時,嘗試強制使用你想要的算法解決問題。強制使用鏈接算法的語句:select * from t1 left join t2 on t1.id=t2.id option(Hash/Loop/Merge Join)

九、看到不是你想要的聚合算法是,嘗試強制使用你想要的聚合算法。強制使用聚合算法的語句示例:select  age ,count(age) as cnt from t1 group by age  option(order/hash group)

十、看到不是你想要的解析執行順序是,或這解析順序耗時過大時,嘗試強制使用你定的執行順序。option(force order)

十一、看到有多個線程來合併執行你的sql語句而影響到性能時,嘗試強制是不併行操做。option(maxdop 1)

十二、在存儲過程當中,因爲參數不一樣致使執行計劃不一樣,也影響啦性能時嘗試指定參數來優化。option(optiomize for(@name='zlh'))

1三、不操做多餘的列,多餘的行,不作務必要的聚合,排序。

相關文章
相關標籤/搜索