SQLSERVER执行计划详解
序言
本篇主要目的有二:
1、看懂t-sql的執(zhí)行計劃,明白執(zhí)行計劃中的一些常識。
2、能夠分析執(zhí)行計劃,找到優(yōu)化sql性能的思路或方案。
如果你對sql查詢優(yōu)化的理解或常識不是很深入,那么推薦幾騙博文給你:SqlServer性能檢測和優(yōu)化工具使用詳細,sql語句的優(yōu)化分析,T-sql語句查詢執(zhí)行順序。
執(zhí)行計劃簡介
1、什么是執(zhí)行計劃?
大哥提交的sql語句,數據庫查詢優(yōu)化器,經過分析生成多個數據庫可以識別的高效執(zhí)行查詢方式。然后優(yōu)化器會在眾多執(zhí)行計劃中找出一個資源使用最少,而不是最快的執(zhí)行方案,給你展示出來,可以是xml格式,文本格式,也可以是圖形化的執(zhí)行方案。
2、預估執(zhí)行計劃,實際執(zhí)行計劃
選擇語句,點擊上面其中一個執(zhí)行計劃,預估執(zhí)行計劃可以立即顯示,而實際執(zhí)行計劃則需要執(zhí)行sql語句后出現。預估執(zhí)行計劃不等于實際執(zhí)行計劃,但是絕大多數情況下實際的執(zhí)行計劃跟預估執(zhí)行計劃都是一致的。統(tǒng)計信息變更或者執(zhí)行計劃重編譯等情況下,會造成不同。
3、為什么要讀懂執(zhí)行計劃
首先執(zhí)行計劃讓你知道你復雜的sql到底是怎么執(zhí)行的,有沒有按照你想的方案執(zhí)行,有沒有按照最高效的方式執(zhí)行,使用啦眾多索引的哪一個,怎么排序,怎么合并數據的,有沒有造成不必要資源浪費等等。官方數據顯示,執(zhí)行t-sql存在問題,80%都可以在執(zhí)行計劃中找到答案。
4、針對圖形化執(zhí)行計劃分析
執(zhí)行計劃,可以以文本,xml,圖形化展示出來。本騙主要以圖形化執(zhí)行計劃主導進行分析,然而執(zhí)行計劃中包含78個可用的操作符,本篇也只能對常用的進行分析,常用的幾乎就包含你日常所有的了。Msdn上有圖片介紹:https://msdn.microsoft.com/zh-cn/library/ms175913(v=sql.90).aspx
5、怎么看執(zhí)行計劃
圖形化執(zhí)行計劃是從上到下從又到左看的。
6、清除緩存的執(zhí)行計劃
dbcc freeprocache
dbcc flushprocindb(db_id)
看懂圖形化執(zhí)行計劃
1、連線
1、越粗表示掃描影響的行數愈多。
2、Actual Number of Rows 掃描中實際影響的的行數。
3、EstimatedNumber of Rows 預估掃描影響的行數。
4、Estimated row size操作符生成的行的估計大小(字節(jié))。
5、Estimated Data Size 預估影響的數據的大小。
2、Tooltips,當前步驟執(zhí)行信息
Note:這個tips的信息告訴我們執(zhí)行的對象是什么,采用的操作操作是什么,查找的數據是什么,使用的索引是什么,排序與否,預估cpu、I/O、影響行數,實際行數等信息。具體參數清單參見msdn:https://msdn.microsoft.com/zh-cn/library/ms178071(v=sql.90).aspx
3、Table Scan(表掃描)
當表中沒有聚集索引,又沒有合適索引的情況下,會出現這個操作。這個操作是很耗性能的,他的出現也意味著優(yōu)化器要遍歷整張表去查找你所需要的數據。
4、Clustered Index Scan(聚集索引掃描)、Index Scan(非聚集索引掃描)
這個圖標兩個操作都可以使用,一個聚集索引掃描,一個是非聚集索引掃描。
聚集索引掃描:聚集索引的數據體積實際是就是表本身,也就是說表有多少行多少列,聚集所有就有多少行多少列,那么聚集索引掃描就跟表掃描差不多,也要進行全表掃描,遍歷所有表數據,查找出你想要的數據。
非聚集索引掃描:非聚集索引的體積是根據你的索引創(chuàng)建情況而定的,可以只包含你要查詢的列。那么進行非聚集索引掃描,便是你非聚集中包含的列的所有行進行遍歷,查找出你想要的數據。
5、Key Lookup(鍵值查找)
首先需要說的是查找,查找與掃描在性能上完全不是一個級別的,掃描需要遍歷整張表,而查找只需要通過鍵值直接提取數據,返回結果,性能要好。
當你查找的列沒有完全被非聚集索引包含,就需要使用鍵值查找在聚集索引上查找非聚集索引不包含的列。
6、RID Lookoup(RID查找)
跟鍵值查找類似,只不過RID查找,是需要查找的列沒有完全被非聚集索引包含,而剩余的列所在的表又不存在聚集索引,不能鍵值查找,只能根據行表示Rid來查詢數據。
7、Clustered Index Seek(聚集索引查找)、Index Seek(非聚集索引查找)
聚集索引查找和非聚集索引查找都是使用該圖標。
聚集索引查找:聚集索引包含整個表的數據,也就是在聚集索引的數據上根據鍵值取數據。
非聚集索引查找:非聚集索引包含創(chuàng)建索引時所包含列的數據,在這些非聚集索引的數據上根據鍵值取數據。
8、Hash Match
這個圖標有兩種地方用到,一種是表關聯(lián),一種是數據聚合運算時。
再分別說這兩中運算的前面,我先說說Hashing(編碼技術)和Hash Table(數據結構)。
Hashing:在數據庫中根據每一行的數據內容,轉換成唯一符號格式,存放到臨時哈希表中,當需要原始數據時,可以給還原回來。類似加密解密技術,但是他能更有效的支持數據查詢。
Hash Table:通過hashing處理,把數據以key/value的形式存儲在表格中,在數據庫中他被放在tempdb中。
接下來,來說說Hash Math的表關聯(lián)跟行數據聚合是怎么操作運算的。
表關聯(lián):
如上圖,關聯(lián)兩個數據集時,Hash Match會把其中較小的數據集,通過Hashing運算放入HashTable中,然后一行一行的遍歷較大的數據集與HashTable進行相應的匹配拉取數據。
數據聚合:當查詢中需要進行Count/Sum/Avg/Max/Min時,數據可能會采用把數據先放在內存中的HashTable中然后進行運算。
9、Nested Loops
這個操作符號,把兩個不同列的數據集匯總到一張表中。提示信息中的Output List中有兩個數據集,下面的數據集(inner set)會一一掃描與上面的數據集(out set),知道掃描完為止,這個操作才算是完成。
10、Merge Join
這種關聯(lián)算法是對兩個已經排過序的集合進行合并。如果兩個聚合是無序的則將先給集合排序再進行一一合并,由于是排過序的集合,左右兩個集合自上而下合并效率是相當快的。
11、Sort(排序)
對數據集合進行排序,需要注意的是,有些數據集合在索引掃描后是自帶排序的。
12、Filter(篩選)
根據出現在having之后的操作運算符,進行篩選
13、Computer Scalar
在需要查詢的列中需要自定義列,比如count(*) as cnt ,select name+''+age 等會出現此符號。
根據執(zhí)行計劃細節(jié)要做的優(yōu)化操作
這里會有很多建議給出,我不一一舉例了,給出幾個示例,想做到優(yōu)化行家,多的還需要大家去悟去理解。
1、如果select * 通常情況下聚集索引會比非聚集索引更優(yōu)。
2、如果出現Nested Loops,需要查下是否需要聚集索引,非聚集索引是否可以包含所有需要的列。
3、Hash Match連接操作更適合于需要做Hashing算法集合很小的連接。
4、Merge Join時需要檢查下原有的集合是否已經有排序,如果沒有排序,使用索引能否解決。
5、出現表掃描,聚集索引掃描,非聚集索引掃描時,考慮語句是否可以加where限制,select * 是否可以去除不必要的列。
6、出現Rid查找時,是否可以加索引優(yōu)化解決。
7、在計劃中看到不是你想要的索引時,看能否在語句中強制使用你想用的索引解決問題,強制使用索引的辦法Select CluName1,CluName2 from Table with(index=IndexName)。
8、看到不是你想要的連接算法時,嘗試強制使用你想要的算法解決問題。強制使用連接算法的語句:select * from t1 left join t2 on t1.id=t2.id option(Hash/Loop/Merge Join)
9、看到不是你想要的聚合算法是,嘗試強制使用你想要的聚合算法。強制使用聚合算法的語句示例:select age ,count(age) as cnt from t1 group by age option(order/hash group)
10、看到不是你想要的解析執(zhí)行順序是,或這解析順序耗時過大時,嘗試強制使用你定的執(zhí)行順序。option(force order)
11、看到有多個線程來合并執(zhí)行你的sql語句而影響到性能時,嘗試強制是不并行操作。option(maxdop 1)
12、在存儲過程中,由于參數不同導致執(zhí)行計劃不同,也影響啦性能時嘗試指定參數來優(yōu)化。option(optiomize for(@name='zlh'))
13、不操作多余的列,多余的行,不做務必要的聚合,排序。
小結
已經到晚間2點半啦,查詢優(yōu)化沒有做過于詳細的分解,見諒,如果你在看到本文后有什么疑問,歡迎加入博客左上角群,一起交流學習,安。
總結
以上是生活随笔為你收集整理的SQLSERVER执行计划详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Should we ban guns 英
- 下一篇: 信用卡用得少会降额吗?这得看你是如何用卡