MySQL覆蓋索引
阿新 • • 發佈:2021-10-25
一個索引包含所有需要查詢的欄位,稱之為"覆蓋索引"
覆蓋索引,查詢只需要掃描索引而無須回表,優點
索引條目遠小於資料行大小,如果只需要讀取索引,MySQL會極大減少資料訪問量
- 這對快取負載非常重要,這種情況下響應時間大部分花在資料拷貝上
- 對IO密集型應用也有幫助,索引更容易全部放入記憶體中
索引按照列值順序儲存的,對於IO密集型查詢範圍會比隨機從磁碟讀取每一行資料IO要少得多
由於InnoDB聚簇索引,覆蓋索引對InnoDB特別有用
InnoDB中,二級索引在葉子節點中儲存了行的主鍵值
若二級主鍵能夠覆蓋查詢,可以避免對主鍵索引二次查詢
覆蓋索引必須要儲存索引列的值
雜湊索引,空間索引和全文索引等不儲存索引列的值,MySQL只能用B-Tree索引做覆蓋索引
索引覆蓋查詢
在 EXPLAIN 的 Extra 列看到 Using index 資訊,這個查詢就是一個索引覆蓋查詢
MySQL查詢優化器在執行查詢前會判斷是否有一個索引能進行覆蓋,如果是false也會回表獲取資料行
MySQL不能在索引中執行LIKE操作,但是支援在索引中做最左字首匹配的LIKE比較
延遲關聯(deferred join)
先擴充套件索引到查詢涉及的所有列,然後重寫查詢
這種方式延遲了對列的訪問,所以叫做延遲關聯
在查詢的第一階段MySQL可以使用覆蓋索引,在FROM子句的子查詢找到匹配的prod_id
根據這些prod_id值在外層查詢匹配獲取需要的所有列值
優化效果取決於WHERE條件匹配返回的行
測試結果
第一個資料集,查詢返回的結果集很大,大部分時間都在讀取和傳送資料
第二個資料集,經過索引過濾,返回了很少的結果集
第三個資料集,索引過濾時符合第一個條件的結果集已經很小了,子查詢帶來的成本反而更高
論讀書睜開眼,書在面前 閉上眼,書在心裡