统计--过滤(筛选)索引的统计信息过期问题测试
基礎(chǔ)知識普及:
對于篩選索引,MSDN如是說:
篩選索引是一種經(jīng)過優(yōu)化的非聚集索引,尤其適用于涵蓋從定義完善的數(shù)據(jù)子集中選擇數(shù)據(jù)的查詢。 篩選索引使用篩選謂詞對表中的部分行進行索引。 與全表索引相比,設(shè)計良好的篩選索引可以提高查詢性能、減少索引維護開銷并可降低索引存儲開銷。
篩選索引與全表索引相比具有以下優(yōu)點:
提高了查詢性能和計劃質(zhì)量 設(shè)計良好的篩選索引可以提高查詢性能和執(zhí)行計劃質(zhì)量,因為它比全表非聚集索引小并且具有經(jīng)過篩選的統(tǒng)計信息。? 與全表統(tǒng)計信息相比,經(jīng)過篩選的統(tǒng)計信息更加準(zhǔn)確,因為它們只涵蓋篩選索引中的行。
減少了索引維護開銷 僅在數(shù)據(jù)操作語言 (DML) 語句對索引中的數(shù)據(jù)產(chǎn)生影響時,才對索引進行維護。? 與全表非聚集索引相比,篩選索引減少了索引維護開銷,因為它更小并且僅在索引中的數(shù)據(jù)更改時才進行維護。 篩選索引的數(shù)量可以非常多,特別是在其中包含很少更改的數(shù)據(jù)時。 同樣,如果篩選索引只包含頻繁修改的數(shù)據(jù),則索引大小較小時可以減少更新統(tǒng)計信息的開銷。
減少了索引存儲開銷 在沒必要創(chuàng)建全表索引時,創(chuàng)建篩選索引可以減少非聚集索引的磁盤存儲開銷。? 可以使用多個篩選索引替換一個全表非聚集索引而不會明顯增加存儲需求。
MSDN地址:http://msdn.microsoft.com/zh-cn/library/cc280372(v=sql.105).aspx
?--========================================================
基礎(chǔ)案例介紹:
在很多場景中,過濾索引能解決很多復(fù)合索引無法處理的問題,成為一些特殊問題的必殺技,如下面的查詢:
SELECT TOP(10) C2 FROM TB1 WHERE C1>5 ORDER BY C2 DESC如果按C2倒序排序后,排在結(jié)果集前面的大多數(shù)行都滿足C1>5的條件的話,那么我們可以建立以下索引來優(yōu)化:
CREATE INDEX IDX_C2_INC ON TB1(C2) INCLUDE(C1)但如果滿足C1>5的行特別少或者排在結(jié)果集尾部的話,那么查詢需要遍歷索引的大部分才能找到匹配的數(shù)據(jù)返回給客戶,從而導(dǎo)致大量邏輯IO開銷。
如果滿足C1>5的行比較少,那么可以使用以下索引來優(yōu)化:
CREATE INDEX IDX_C1_C2 ON TB1(C1,C2)雖然以上索引能幫助快速找到所有C1<5的行,但仍需要經(jīng)過一次排序后才能獲得TOP(5)的數(shù)據(jù),而排序又會導(dǎo)致CPU資源開銷。
隨著SQL SERVER 2008引入過濾索引后,這樣的查詢便可以輕松搞定,我們只需要建立以下索引:
CREATE INDEX IDX_C2_WH ON TB1(C2) WHERE C1>5查詢可以通過索引很快找到滿足C1>5并且按C2排序的TOP 5的數(shù)據(jù),最小化地消耗CPU和IO資源。
--===========================================================
在SQL Server中,數(shù)據(jù)庫選擇的“自動創(chuàng)建統(tǒng)計(Auto Create Statistics)”選項默認(rèn)為開啟狀態(tài), 隨著索引的創(chuàng)建,數(shù)據(jù)庫會自動創(chuàng)建與之對應(yīng)的統(tǒng)計信息,創(chuàng)建過濾索引的過程同樣會創(chuàng)建對于的統(tǒng)計信息。
當(dāng)數(shù)據(jù)庫設(shè)置為自動更新統(tǒng)計時(數(shù)據(jù)庫未開啟跟蹤標(biāo)志情況下),SQL Server 監(jiān)控表中的數(shù)據(jù)更改,當(dāng)更改滿足一下條件之一時更新:
1.向空表插入數(shù)據(jù)時
2.少于500行的表增加500行或者更多
3.當(dāng)表中行多于500行時,數(shù)據(jù)的變化量大于20%時
(在SQL SERVER 2000中,指的是20%的行被修改,而在SQL SERVER 2005/2008中,指的是20%的列數(shù)據(jù)被修改)
PS: 20%不是一個絕對值
--===========================================================
那么問題出來了,這個20%比例對過濾索引的統(tǒng)計信息是否滿足呢?如果滿足的話,哪基數(shù)是什么呢?是表中的數(shù)據(jù)還是當(dāng)前滿足條件的數(shù)據(jù)呢?
讓我們來做個測試吧
首先準(zhǔn)備測試數(shù)據(jù)
--創(chuàng)建表,并插入5000行數(shù)據(jù) SELECT TOP(5000) IDENTITY(INT,1,1) AS ID, * INTO TB001 FROM SYS.all_columns GO --創(chuàng)建聚簇索引 CREATE CLUSTERED INDEX IDX_ID ON TB001(ID) GO --創(chuàng)建過濾索引 CREATE INDEX IDX_COLUMNID ON TB001(object_id) WHERE Column_id<3 GO --再導(dǎo)入25000行數(shù)據(jù) INSERT INTO TB001 SELECT TOP(5000) * FROM SYS.all_columns GO 5 --更新統(tǒng)計信息 UPDATE STATISTICS TB001 GO查看過濾索引的統(tǒng)計信息
--查看過濾索引的統(tǒng)計信息 DBCC SHOW_STATISTICS('dbo.TB001','IDX_COLUMNID') GO目前表中有30000行數(shù)據(jù),滿足條件的數(shù)據(jù)是5412行,都超過500行的限制,考慮20%這是一個參考值而不是絕對值,我們測試值調(diào)整到50%;為了避免版本問題導(dǎo)致更新行還是更新列的問題,我們統(tǒng)一使用插入方式來測試。
1.首先測試插入5412*50%=2706行數(shù)據(jù)
--再導(dǎo)入2706行數(shù)據(jù) INSERT INTO TB001 SELECT TOP(2706) * FROM SYS.all_columns GO --執(zhí)行查詢嘗試觸發(fā)統(tǒng)計更新 SELECT TOP(1) object_id,COUNT(1)FROM TB001
WHERE Column_id<3
GROUP BY object_id
ORDER BY COUNT(1) DESC --查看過濾索引的統(tǒng)計信息 DBCC SHOW_STATISTICS('dbo.TB001','IDX_COLUMNID') GO
統(tǒng)計信息未發(fā)生變化,仍舊是:
2.首先測試插入30000*50%=15000行數(shù)據(jù)(需要考慮之前已插入的2706條數(shù)據(jù))
--再導(dǎo)入25000行數(shù)據(jù) INSERT INTO TB001 SELECT TOP(5000) * FROM SYS.all_columns GO INSERT INTO TB001 SELECT TOP(5000) * FROM SYS.all_columns GO --由于之前插入2706條數(shù)據(jù),因此第三次插入2294 INSERT INTO TB001 SELECT TOP(2294) * FROM SYS.all_columns GO SELECT COUNT(1) FROM TB001--執(zhí)行查詢嘗試觸發(fā)統(tǒng)計更新 SELECT TOP(1) object_id,COUNT(1)FROM TB001
WHERE Column_id<3
GROUP BY object_id
ORDER BY COUNT(1) DESC GO --查看過濾索引的統(tǒng)計信息 DBCC SHOW_STATISTICS('dbo.TB001','IDX_COLUMNID') GO
感謝上蒼,感謝黨,統(tǒng)計更新了,世界和平了,媽媽再也不用擔(dān)心我的成績了(畢業(yè)很多年啦,淚流滿面啊)!!!
--=====================================================
在測試過程中,最開始想使用以下查詢來觸發(fā):
SELECT TOP(1) object_id FROM TB001 WHERE Column_id<3 AND Column_id=82873218 ORDER BY object_id GO SELECT COUNT(1) FROM TB001 WHERE Column_id<3 GO結(jié)果得出一個錯誤結(jié)論,經(jīng)多次測試后才發(fā)現(xiàn)上述兩個查詢雖然使用到索引,但是無法觸發(fā)統(tǒng)計更新。
--=====================================================
總結(jié):無論是復(fù)合索引還是過濾索引的統(tǒng)計信息,都是以上一次統(tǒng)計信息更新時表的行數(shù)作為基數(shù),當(dāng)更新達(dá)到按20%左右的比例左右后,由查詢執(zhí)行來觸發(fā)統(tǒng)計自動更新。
PS1: 更新數(shù)指的是操作影響的行數(shù),如執(zhí)行10次UPDATE操作,每次UPDATE影響50行數(shù)據(jù),那么更新數(shù)為500,即使這10次UPDATE沒有改變?nèi)魏我粭l數(shù)據(jù)(類似UPDATE T1 SET C1=C1這類操作)
PS2: 即使更新數(shù)達(dá)到20%左右,查詢使用到該過濾索引,也不一定會觸發(fā)統(tǒng)計更新,只有查詢優(yōu)化器認(rèn)為該統(tǒng)計過期并且需要一個更新過的統(tǒng)計信息來生成執(zhí)行計劃時,才會觸發(fā)統(tǒng)計自動更新
PS2:由于過濾索引的只存放滿足過濾條件的數(shù)據(jù)的特殊性,存在一些場景下,索引數(shù)據(jù)變化很多而對應(yīng)的統(tǒng)計信息尚未滿足過期(無效)條件,從而導(dǎo)致生成不高效的執(zhí)行計劃,因此有很多高手大神都建議專門針對這些有過濾條件的統(tǒng)計信息制定更新計劃,提高其更新頻率
PS3:除創(chuàng)建過濾索引會生成有過濾條件的統(tǒng)計信息外,數(shù)據(jù)庫管理員也可以主動添加有過濾條件的統(tǒng)計信息,供執(zhí)行優(yōu)化器使用。
--=============================================
漂亮妹子看多了,來點普通的,哈哈
?
轉(zhuǎn)載于:https://www.cnblogs.com/TeyGao/p/4050972.html
總結(jié)
以上是生活随笔為你收集整理的统计--过滤(筛选)索引的统计信息过期问题测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【IOS】Target membersh
- 下一篇: CUDA编程入门极简教程