什么是臨界點(diǎn)?
我們提供的服務(wù)有:成都做網(wǎng)站、成都網(wǎng)站建設(shè)、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、天河ssl等。為千余家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的天河網(wǎng)站制作公司
注意,我要說(shuō)的問題是非聚集索引的執(zhí)行計(jì)劃從Seek+Lookup變成Table/Clustered Index Scan的臨界點(diǎn)。SQL Server的訪問數(shù)據(jù)的IO最小單元是頁(yè)。
我們知道聚集索引的葉級(jí)是數(shù)據(jù)頁(yè),非聚集索引的葉級(jí)是指向數(shù)據(jù)行的指針。所以通過(guò)聚集索引獲取數(shù)據(jù)時(shí),就是直接訪問聚集索引本身,而通過(guò)非聚集索引獲取數(shù)據(jù)時(shí),除了訪問自身,還要通過(guò)指針去訪問數(shù)據(jù)頁(yè)。這個(gè)過(guò)程就是RID/Key Lookup。而此Lookup是一個(gè)單頁(yè)操作,即每次使用一個(gè)RID/Key,然后去訪問對(duì)應(yīng)的一個(gè)數(shù)據(jù)頁(yè),然后獲取頁(yè)上的相應(yīng)的數(shù)據(jù)行。可能當(dāng)前數(shù)據(jù)頁(yè)的有多個(gè)數(shù)據(jù)行是符合查詢要求的,但是一次lookup,只能取當(dāng)前的RID/Key指定的數(shù)據(jù)行。所以同一個(gè)數(shù)據(jù)頁(yè),可能要被訪問很多次。例如,現(xiàn)在lookup要去找RID為2,3,5,7,9對(duì)應(yīng)的數(shù)據(jù)行,而這5個(gè)數(shù)據(jù)行都存在數(shù)據(jù)頁(yè)N上,則數(shù)據(jù)頁(yè)N只少要被訪問5次。
在Seek時(shí),如果要返回N行數(shù)據(jù),則Seek操作至少要訪問N次數(shù)據(jù)頁(yè)。當(dāng)Lookup訪問次數(shù)據(jù)超過(guò)了全表數(shù)據(jù)頁(yè)的總數(shù)時(shí),就會(huì)出現(xiàn)臨界點(diǎn)。這個(gè)時(shí)候Scan操作成本要比Lookup低。超過(guò)這個(gè)臨界點(diǎn)時(shí),查詢優(yōu)化器一般會(huì)選擇Scan替代Seek+Lookup。例如表T有100000行,每頁(yè)存放100行,共有1000頁(yè)。查詢1000條數(shù)據(jù),理論/理想情況下:Scan最少時(shí)只需要10次IO,Lookup只少需要1000次IO。
需要注意的是覆蓋索引中不存在RID/Key,而是對(duì)應(yīng)的列值,所以不會(huì)出現(xiàn)這個(gè)問題。
臨界點(diǎn)什么時(shí)候出現(xiàn)?
前面說(shuō)的理論和原理上的東西,而實(shí)際臨界點(diǎn)的出現(xiàn)由很多因素決定。但主要與表的總頁(yè)數(shù)相關(guān)。臨界點(diǎn)大概出現(xiàn)在訪問頁(yè)占全表頁(yè)數(shù)的25%~33%時(shí)。為了直觀,通常把頁(yè)數(shù)再轉(zhuǎn)換成行數(shù)來(lái)分析。轉(zhuǎn)換時(shí)需要注意,前面闡明Lookup是單頁(yè)操作,所以頁(yè)數(shù)=行數(shù)。
一個(gè)表總行數(shù)為1,000,000,每頁(yè)存放2條行數(shù),共500,000頁(yè)。則25%=125,000,33%=166,000。臨界點(diǎn)會(huì)出現(xiàn)在125,000頁(yè)和166,000頁(yè)間。轉(zhuǎn)換成行表示就是125000/(2*500000)=12.5%,166000/(2*500000)=16.6%。也就是說(shuō)當(dāng)返回行數(shù)小于62400(500000*12.55)時(shí),很可能會(huì)使用Lookup。當(dāng)返回行數(shù)大于83000時(shí),很可能會(huì)使用Scan。這個(gè)表的行太寬了,一個(gè)頁(yè)只能存放2行數(shù)據(jù),從百分比看起來(lái)沒有什么太大感覺。
一個(gè)表總行數(shù)為1,000,000,每頁(yè)存放100條行數(shù),共10,000頁(yè)。則25%=2500,33%=3300。轉(zhuǎn)換成行2500/1000000=0.25%,3300/1000000=0.33%。它的臨界點(diǎn)上限不超過(guò)0.5%。也就是說(shuō)你查詢表中不到0.5%的行數(shù)時(shí),會(huì)全表掃描。
一個(gè)表總行數(shù)為1,000,000,每頁(yè)存放20條行數(shù),共50,000頁(yè)。則25%=125,00,33%=166,00。轉(zhuǎn)換成行表示就是125000/(2*500000)=1.25%,166000/(2*500000)=1.66%。
不難發(fā)現(xiàn),臨界點(diǎn)判斷,對(duì)于大表的查詢性能是有很大幫助的。而對(duì)于小表而言,幾乎都會(huì)是Scan,但是數(shù)據(jù)庫(kù)有緩存機(jī)制,小表會(huì)完整緩存,掃描影響也不大。
我們能做些什么?
1.很容易想到,既然表有Seek對(duì)應(yīng)的索引,我們使用Hint強(qiáng)制使用Seek,問題不就解決了。這個(gè)不一定,本來(lái)這個(gè)問題的出現(xiàn)就是查詢優(yōu)化器認(rèn)為Scan比Lookup的成本要低。如果你強(qiáng)制可能會(huì)適得其反。SQL Server的查詢優(yōu)化器是很強(qiáng)大和智能的,除非你嚴(yán)格測(cè)試過(guò),證明ForceSeek性能更好一些。
2.建立一個(gè)覆蓋索引消除Lookup操作。
示例分析
使用AdventureWorks2012的Sales.SalesOrderDetail。在ProductID列有一個(gè)非聚集索引IX_SalesOrderDetail_ProductID。
通過(guò)下的查詢可以知道表有121317行,共1237個(gè)數(shù)據(jù)頁(yè),每頁(yè)大約存放98行數(shù)據(jù)。由此我們可以預(yù)估一下臨界點(diǎn)在(309行,408行)附近。
select page_count,record_count from sys.dm_db_index_physical_stats(db_id(),object_id(N'Sales.SalesOrderDetail'),1,null,'detailed') where index_level=0
然后再統(tǒng)計(jì)一下不同的ProductID在表中行數(shù),好針對(duì)性的測(cè)試不同ProductID:
select ProductID,COUNT(*) as cnt from Sales.SalesOrderDetail group by ProductID order by cnt
通過(guò)上面查詢,我們知道ProductID=882在表中有407行,可以看到它還是使用Lookup的方式。它的IO計(jì)數(shù)為:
Table 'SalesOrderDetail'. Scan count 1, logical reads 1258
ProductID=751在表中有409行,它就使用了Scan的方式。它的IO計(jì)數(shù)為:
Table 'SalesOrderDetail'. Scan count 1, logical reads 1246
我們還可以測(cè)試其它的返回行數(shù)更多的ProductID,如果是掃描的方式則IO都是在1246,如果是Lookup則都會(huì)高于1246。證明跟理論還是契合的。
就算500行返回才會(huì)超過(guò)臨界點(diǎn),而500行也只占總行數(shù)的500/121317=0.41%。也就是說(shuō)當(dāng)返回行數(shù)超過(guò)全表的0.41%時(shí),優(yōu)化器就認(rèn)為它的篩選度不夠高了,不用seek+lookup,要掃描了。
總結(jié)
1. 當(dāng)遇到"明明有索引,為什么會(huì)掃描?",臨界點(diǎn)的問題可能是原因之一。
2. 因?yàn)榇嬖谂R界點(diǎn),所以非覆蓋非聚集索引的使用率可能沒有我們想象的高。
參考
http://www.sqlskills.com/blogs/kimberly/the-tipping-point-query-answers/
標(biāo)題名稱:非聚集索引中的臨界點(diǎn)(TippingPoint)
分享路徑:http://chinadenli.net/article30/giespo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、做網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)公司、關(guān)鍵詞優(yōu)化、域名注冊(cè)、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)