關於索引的執行計劃記載

dotaddjj發表於2011-10-26

對於sql我們經常看見執行計劃,剛好接觸了資料自己就忍不住整理了一下。

1 全表掃描 full table scans FTS

全表掃描oracle需要讀取表中所有行,然後檢索合格條件的資料,而一次I/O讀取資料塊的多少則是由引數db_block_multiblock_read_count引數設定的,而不是隻讀取一個資料塊,這極大的減少I/O總次數,提高系統吞吐量,一般全表掃描才使用多塊讀操作。

當然大表的全表掃描是很消耗資源的,除非取出資料比較多,大概超過資料的總量的5%-10%,或者使用並行查詢。(其中在cbo最佳化器下 索引利用與否oracle可以更好的判斷,而經常能做的是索引長時間執行後予以重建 最佳化查詢速度)

不過對於上述的超過5%~10%比例個人測試並不一定,只是一般而且oracle會選擇執行計劃消耗最小的sql來執行,所以有時候是否利用索引和全表掃描在cbo中並不是絕對。

2 透過rowid的表讀取 table access by rowidrowid lookup(不過rowid lookep測試中沒有發現此類執行計劃)

使用rowid存取一次I/O只能讀取一個資料塊,和全表掃描多塊讀取不同,如透過索引查詢資料時

select * from test05 where owner=upper('OUTLN')

SELECT STATEMENT, GOAL = RULE

TABLE ACCESS BY INDEX ROWID ASHUANG TEST05

INDEX RANGE SCAN ASHUANG INDEX_TEST05

test05owner有索引,可以看出應用索引用到索引葉塊上記錄的rowid讀取

3 索引掃描index scanindex lookep索引查詢(不過index lookep測試中沒有發現此類執行計劃)

利用索引大家都可能清楚了,這裡提出利用索引查詢資料,在索引中查詢rowid和利用rowid查詢具體的資料都是單獨的I/O,所以對於where查詢的條件的資料不是很多,很可能選擇全表掃描。

還有提出一個唯一索引和非唯一索引的執行基本相同,有區別的是index unique scan是找到合適的值例如where x=’sys’後就停止查詢,因為索引的列值唯一,而index range scan還會順序繼續查詢。

還會可能存在

select owner from test05 where owner=upper('OUTLN')

SELECT STATEMENT, GOAL = RULE

INDEX RANGE SCAN ASHUANG INDEX_TEST05

此種情況,此時oracle只會掃描索引表而test05不會去掃描,因為owner關鍵字的值已經儲存在索引中了。

其實索引是順序的,裡面已經按關鍵字進行了排序,如果能按關鍵字排序查詢,也就避免了進一步排序操作。

除了上述的index unique scanindex range scan還有index full scan索引全掃描index fast full scan索引快速掃描

Index full scan

有全表掃描也就有全索引掃描,同樣支援多塊讀取。

select owner from test05 order by owner

不過個人在測試中並沒有出現上述索引全掃描的執行計劃而是一個全表掃描的執行計劃?

同樣地索引快速掃描於index full scan類似只是少了一個對查詢資料進行排序的過程,當然這種返回方式,可以使用多塊讀功能和並行讀入,獲得最大吞吐量提高性質效率。

select owner from test05

同上測試中還是沒有發覺上述索引快速掃描的執行計劃,還是一個全表掃描。

不過下面的sql

select count(owner) from test05

INDEX FAST FULL SCAN

卻是一個索引快速掃描,看來自己的理解還遠遠不夠。

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25362835/viewspace-1055970/,如需轉載,請註明出處,否則將追究法律責任。

相關文章