全表掃描和全索引掃描

xuexiaogang發表於2023-02-16

      有人向我提問: oracle 的select count(*) from table 不走索引,mysql(版本>=5.7) select count(*) from table是自動走索引的,是這樣嗎?因為提問題的人查過MySQL的count(*)是做過最佳化的。

要回答這個問題,還是用實驗來說明。在Oracle 19C中,我們建立一個表,並且寫入100萬資料。如圖1

全表掃描和全索引掃描

                                                                                       圖1

使用Oracle的執行跟蹤 set autotrace on; 從實際執行的情況看資料庫具體的執行消耗,這樣的執行計劃更加準備。如圖2

全表掃描和全索引掃描

                                                                                   圖2

我們看到了 INDEX FAST FULL SCAN。

如果我們查一個不帶索引的列,那麼比如發生的是全表掃描。如圖3

全表掃描和全索引掃描

                                                                                     圖3

那麼我們來看MySQL的。只用5條就可以說明問題了。xxg表有一個主鍵。(必須有主鍵,沒有主鍵就不是這個效果了)。注意看下圖有extra中有一個using index。這個在MySQL中叫做索引覆蓋。如圖4

全表掃描和全索引掃描

                                                                                                                            圖4

索引覆蓋的意思是僅僅用到了索引,其他沒用到。type這裡顯示的是 index    比如一個表有50列,該表有50G,如果每列長度大致相當,那麼其中一列大約有1/50的大小,即1G左右。索引覆蓋就是查1G的索引就行,而不是掃描50G。這個就和Oracle中的INDEX FAST FULL SCAN有點相似了。

如果說MySQL對count(*)做了最佳化,那麼也可以說Oracle對count(*)也做了最佳化。其實我設想,可能就是這樣設計的。Oracle和MySQL在這個場景上是一致的。所以不存在一個全表,一個使用索引的區別。(我個人其實覺得全索引掃描、全索引覆蓋掃描是用到了索引,但是和我們通常說的用到索引返回少量資料還是有一點區別的)

當然如果沒有用到索引,type這裡顯示的就是ALL了。請看下圖5。那麼和Oracle的 TABLE ACCESS FULL也是一樣的。

全表掃描和全索引掃描

                                                                                   圖5


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

相關文章