SqlServer 索引自動優(yōu)化工具
整個思路是這樣的,索引都是為查詢和更新服務(wù)的,但是不合適的索引又會對插入和更新帶來負面影響。面對表上現(xiàn)有的索引想識別那些是有效的不太可能。那么根據(jù)現(xiàn)有的數(shù)據(jù)使用情況重建所有的新索引不就解決了嘛。根據(jù)查詢生成全新索引,然后和現(xiàn)有對比,不吻合的全部刪除,原來沒有的創(chuàng)建。雖然說對于正在運行的系統(tǒng)來說風(fēng)險還是蠻大的。但是可以做臨界測試嘛。
具體解決方案如下:
首先在熱備的數(shù)據(jù)庫服務(wù)器上定期抓取緩存的執(zhí)行計劃(原本想抓取SQL發(fā)現(xiàn)有些SQL實在摻不忍睹,沒有自動化解析的可能性),然后連同該執(zhí)行的執(zhí)行次數(shù)即表的統(tǒng)計信息一起down到一個備用服務(wù)器的數(shù)據(jù)表中。
執(zhí)行計劃積累幾次后,開始解析。由于執(zhí)行計劃是格式良好的XML文件,加上微軟提供執(zhí)行計劃的XSD文件。我們可以反向推出各節(jié)點對應(yīng)的SQL謂詞(這個XSD到現(xiàn)在都沒找到官方的說明,只能反向推出關(guān)聯(lián))。例如建立索引我們比較關(guān)心三類謂詞,分別為:Select,Join,Where。 只要拿到這些我們就能建立良好的索引。原理很簡單,Join和Where都是索引鍵的依據(jù),而Select可以斟請?zhí)砑拥絀ndex的Include中。
解析的時候也不是針對單個執(zhí)行計劃,而是將所有執(zhí)行計劃全分解后進行統(tǒng)計處理。好處就是能夠知道那些表字段被引用的最多,那些是外鍵列。那些數(shù)據(jù)被反復(fù)查詢。例如可以得出TableA的Col1列在一天的業(yè)務(wù)過程中被Join了10W次,被Where2W次。而Col2則被Select了10W次,僅僅被Where了100次。這樣我們建立索引的基礎(chǔ)就是基于表的而不是基于單個查詢的。最終生成的Index將權(quán)衡查詢頻率和查詢的重要性,如果某個業(yè)務(wù)查詢特別重要,但執(zhí)行頻率不高我們可以提供權(quán)重,優(yōu)先建立索引。當(dāng)然創(chuàng)建Index還要參考表的數(shù)據(jù)分布以決定Index中字段的順序。
好了,準備工作完成,開始建索引。當(dāng)前擁有的條件,表數(shù)據(jù)分布,表字段分別被查詢引用次數(shù)(Select,Join,Where),以及這些SQL謂詞出現(xiàn)的次數(shù)。根據(jù)這些如何創(chuàng)建索引開始的想法是逐個分析,考慮所有可能性然后創(chuàng)建。發(fā)現(xiàn)這種方式只適合人腦,讓電腦做得先讓電腦的智商增長到120以上才有可行性。發(fā)現(xiàn)逆向思維這里同樣大有用處,既然不能一下子創(chuàng)建最合適的,那我們就根據(jù)執(zhí)行計劃得出的組合創(chuàng)建所有的Index組合。凡是Join和Where都放到Index的Key里。例如:
select t1.A, t1.B, t1.C, t2.J, t2.k from Table1 t1 Join Table1 t2 on t1.A = t2.j Where t1.A = 'param'
草創(chuàng)的索引就是:
Index(A,B)includ(C) 和 Index(j)include(j,k)
關(guān)于Select如果是小數(shù)據(jù)類型且Alter的執(zhí)行計劃中該數(shù)據(jù)修改頻率很小的都放到Include里去進去。大數(shù)據(jù)類型和修改比較頻繁的就算了。這樣我們剔除相互覆蓋的。部分重疊的,部分重疊到底保留那一個參考執(zhí)行頻率和查詢重要性。差異很小的就合并并為一個,如:
1.Index (A,B,C)Include(D)
2.Index(A,B,D)Include(C)
直接合并為:
Index(A,B)Include(C,D)
當(dāng)然如果Alert的特別少也可以合并成Index(A,B,C,D)這個要參考C,D字段的修改頻率。和主鍵重疊的剔除。這樣留下的基本上就是我們需要的索引了。
對比現(xiàn)有索引進行甄別覆蓋的過程就略過。簡單的拉出來Create Index 進行解析處理就好了。發(fā)布的時候很簡單。寫個腳本在業(yè)務(wù)比較少的時候做Drop和Create就完成了。項目源代碼因為設(shè)計到公司的保密問題就不上傳了。一個注意的地方對于簡單查詢的SQL執(zhí)行計劃緩存的時候會比較短且一旦緩存不夠就會被清理掉。要注意這些SQL的執(zhí)行頻率的誤差。
SqlserverR2 XSD:http://schemas.microsoft.com/sqlserver/2004/07/showplan/sql2008/showplanxml.xsd
總結(jié)的節(jié)點映射列舉如下:
查詢sql執(zhí)行計劃都包含在節(jié)點“StmtSimple”中,如果沒有這個節(jié)點一般就是其它類型的SQL的執(zhí)行計劃。
Join關(guān)聯(lián)的節(jié)點和自身類型有關(guān)一般包含在Hash,Marger中,如何Join同時又是Where條件的話則會出現(xiàn)在SeekKey和Compare節(jié)點中,因為Join的列都是成對出現(xiàn),這里很容易識別,有一個是參數(shù)(@開頭)或常量(type="Const")則必定是Where條件。
Select最終輸出字段比較容易找到,第一個OutputList節(jié)點就是。
需要注意的是有因為一般列每個ColumnReference都包含庫名,表名,列信息,但是系統(tǒng)表則不會。注意剔除。
相關(guān)文章
淺談SQL Server中統(tǒng)計對于查詢的影響分析
SQL Server查詢分析器是基于開銷的。通常來講,查詢分析器會根據(jù)謂詞來確定該如何選擇高效的查詢路線,比如該選擇哪個索引2012-05-05sql2000報錯Successfully re-opened the local eventlog解決方法
這篇文章主要介紹了sql2000報錯Successfully re-opened the local eventlog解決方法,需要的朋友可以參考下2014-12-12SQL Server中參數(shù)化SQL寫法遇到parameter sniff ,導(dǎo)致不合理執(zhí)行計劃重用的快速解決方法
這篇文章主要介紹了SQL Server中參數(shù)化SQL寫法遇到parameter sniff ,導(dǎo)致不合理執(zhí)行計劃重用的快速解決方法的相關(guān)資料,需要的朋友可以參考下2016-07-07SQLServer2019 數(shù)據(jù)庫環(huán)境搭建與使用的實現(xiàn)
這篇文章主要介紹了SQLServer2019 數(shù)據(jù)庫環(huán)境搭建與使用的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04詳解SQL Server數(shù)據(jù)庫架構(gòu)和對象、定義數(shù)據(jù)完整性
本篇文章詳細講解了SQL Server的主鍵約束、唯一約束和外鍵約束這一塊。圖文并茂,方便大家理解與學(xué)習(xí)。有興趣的朋友可以看下2016-12-12SQLServer中數(shù)據(jù)庫文件的存放方式,文件和文件組
上次我關(guān)于索引的文章有幾個園友發(fā)站內(nèi)信問我如何將索引和表存儲在不同的硬盤上。我覺的需要專門寫一篇文章來講述一下文件和文件組應(yīng)該更容易理解2011-12-12教你恢復(fù)SQLSERVER的master系統(tǒng)庫的方法
這篇文章主要介紹了恢復(fù)SQLSERVER的master系統(tǒng)庫,本文介紹可能需要恢復(fù)master數(shù)據(jù)庫的情況以及如何正確完成這些步驟,需要的朋友可以參考下2022-09-09