MySQL優化:如何避免回表查詢


參考:https://www.cnblogs.com/myseries/p/11265849.html

 

InnoDB有兩大類索引:聚集索引(clustered index)和普通索引(secondary index)

 

nnoDB聚集索引的葉子節點存儲行記錄,因此, InnoDB必須要有,且只有一個聚集索引:

(1)如果表定義了PK,則PK就是聚集索引;

(2)如果表沒有定義PK,則第一個not NULL unique列是聚集索引;

(3)否則,InnoDB會創建一個隱藏的row-id作為聚集索引;

 

InnoDB普通索引的葉子節點存儲主鍵值。

 

 

 

 

兩個B+樹索引分別如上圖:

  (1)id為PK,聚集索引,葉子節點存儲行記錄;

  (2)name為KEY,普通索引,葉子節點存儲PK值,即id;

 

既然從普通索引無法直接定位行記錄,那普通索引的查詢過程是怎么樣的呢?

通常情況下,需要掃碼兩遍索引樹。

 

 

 

 這就是所謂的回表查詢,先定位主鍵值,再定位行記錄,它的性能較掃一遍索引樹更低。

 

總結:回表查詢就是查詢時先定位主鍵值,再定位行記錄,會查詢2次索引樹。

 

 

如何實現索引覆蓋?

常見的方法是:將被查詢的字段,建立到聯合索引里去

如將下面第二個查詢中sex加入到聯合索引中,就不需要回表了。

 

select id,name from user where name='shenjian'; 

能夠命中name索引,索引葉子節點存儲了主鍵id,通過name的索引樹即可獲取id和name,無需回表,符合索引覆蓋,效率較高。

explain sql 顯示 Extra:Using index。說明沒有回表

 

select id,name,sex from user where name='shenjian';

能夠命中name索引,索引葉子節點存儲了主鍵id,但sex字段必須回表查詢才能獲取到,不符合索引覆蓋,需要再次通過id值掃碼聚集索引獲取sex字段,效率會降低。

explain sql 顯示 Extra:Using index condition。說明需要回表

 

詳細描述見本文第一行引用的鏈接

select  id, name  from  user  where  name = 'shenjian' ;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM