索引為什麼降低了查詢的速度?

2021-05-26 02:24:37 字數 1092 閱讀 6268

在碩士期間,同學去參加了國內某b2c的公司的面試,回來的時候,很鬱悶的跟我說,面試官問了他乙個資料庫的問題,在乙個查詢中,使用了某個索引所施加的列作為過濾條件(例如:select a,b from t where c=x,其中c是表t的乙個字段,該字段上建立了索引),當資料庫使用該索引時,速度比不使用時反而降低了,請問為啥?結果那哥們很鬱悶的說:不知道。

其實,就我個人看來,這個問題應該很簡單的,主要是很多人在開發資料庫的過程中,其實認為資料庫是個黑匣子,而且沒有相關的dba做支援,沒有去**原理新的東西,所以,一旦遇見這種理論和實際經驗相結合的問題。

在資料庫中,訪問資料的方式,從本質上來說是兩種:一種是隨機讀取,也就是根據資料在磁碟上的位置,讀取某一小部分資料,形象的說,就是小雞在地上啄公尺;另外一種就是順序讀取了,就是將乙個表所在的資料檔案從頭讀到尾,很像是推土機挖礦一樣。前者一般適合少量資料的讀取,後者是適合大量資料的讀取。

在資料庫中,對於面試官所提的sql,實際的查詢計畫有兩種:一種是,先讀取索引中的滿足條件的列所在的磁碟物理位置,然後去根據物理位置,將所在的列讀出,最後過濾出需要的兩列,這個過程會一直迴圈,直至索引上沒有滿足過濾條件的列;而另外一種則是將磁碟上的資料一塊一塊讀入記憶體,然後一條條過濾滿足c=x的列,對於滿足條件的列,輸出所需的a和b列。在這兩種查詢計畫執行的過程中,讀取磁碟的資料的時間佔據了大部分時間,目前scsi磁碟讀取資料的有效速度可能最快不過10m/s吧,而記憶體之間搬運資料以及cpu的計算速度還是相當之快的,各位有興趣可以自己計算。

前者代表了典型的隨機讀取的方式,後者當時是順序讀取的方式。

一般說來,在資料庫的優化器中,比如mysql還是pgsql,對於上面的兩種查詢計畫做選擇的時候,會參考乙個引數,具體叫啥忘記了,這個閾值大概是30%,假如超過了就選擇順序讀取資料,假如沒有,就選擇隨機讀取。這個閾值一般在索引中都會有,記錄了所施加的列中值的分布。而資料庫在執行了一段時間後,這些分布的統計值會和實際值有很大偏差的,這個時候就需要dba出馬對資料庫進行處理了,一般資料庫都會提供相應的工具。

所以,在滿足c=x的資料超過了一定閾值,而資料庫的資料在執行了一定時間後,統計資料不準確時,查詢引擎就會選擇錯誤的查詢計畫,也就是進行隨機讀取大量滿足條件的資料,從而降低了資料的查詢速度。

以上是本人拙見,歡迎拍磚討論

為什麼索引可以提高查詢速度

參考 以下是關於索引的個人理解 有這麼乙個students表 我們執行一條sql語句 select from students where name 老頑童 執行結果 如果我們沒有為name欄位建立索引,這條sql語句是從頭開始一條一條比較的,比較七次 找到了老頑童所在的這一條資料。如果此時我們為n...

我們為什麼要用索引,用索引為什麼比不用索引快

經過老楊的細心指點,我才真正的明白 理解 記住 以前曾看過索引的資料,時間長都忘啦 老楊問我如果一張表上沒有索引,你要查id 5的記錄,資料庫會怎麼做?我說資料庫會先根據資料字典找到這張表,然後根據表頭的記錄找到這張表的資料塊,然後每個資料塊去找。老楊 會把所有的資料塊都掃一遍嗎?我 有可能會,有可...

了解索引為什麼能快速查詢資料

簡單概述 在我們存資料時,如果建立索引。資料庫系統會維護乙個滿足特定查詢演算法的資料結構,這些資料結構以某種方式引用資料 可以在這些資料結構之上,實現高階查詢演算法,這種結構就是索引 一般來說,索引本身也很大,不可能全部儲存在記憶體中,因此索引往往以索引檔案的形式儲存在磁碟上 為了加快資料的查詢,可...