1. 先說什麼是索引?
索引是一種資料結構
不同引擎對索引的實現方式不同,innodb採用b+樹作為索引結構。
2.聚簇索引、非聚簇索引索引可分為聚簇索引和非聚簇索引兩種。
聚簇索引(clustered index):聚簇索引的資料的物理存放順序與索引順序是一致的。
非聚簇索引(二級索引)(secondary index):非聚簇索引記錄的物理順序與邏輯順序沒有必然的聯絡,與資料的儲存物理結構沒有關係。
每個innodb的表中聚簇索引有且只有乙個,而非聚簇索引可以有多個。
聚簇索引按照如下規則建立:3. 回表舉個栗子
假設有個t表(id pk, name key, ***, flag),這裡的id是聚集索引,name則是普通索引。
表中有四條記錄: id
name
***flag1sj
ma3zs
ma5ls
mb9ww
fa聚集索引的b+樹索引(id是pk,葉子節點儲存行記錄):
普通索引的b+樹索引(name是key,葉子節點儲存pk值,即id):
此時使用不同索引對第三條記錄進行查詢:
1.
select name,*** from t where id =
5
其執行過程是:
可看出聚簇索引查詢的會很快,因為可以直接從索引樹中取到想要的資料。
select name,*** from t where name =
"ls"
其執行過程是:
可以看出需要掃瞄兩遍索引樹,第一遍先通過普通索引定位到主鍵值id=5,然後第二遍再通過聚集索引定位到具體行記錄。這就是所謂的回表查詢,即先定位主鍵值,再根據主鍵值定位行記錄,效能相對於只掃瞄一遍聚集索引樹的效能要低一些。
這就是所謂的回表,即先定位主鍵值,再根據主鍵定位行記錄。
那麼,如何避免回表?
答:索引覆蓋(cover index)
4. 索引覆蓋
如果索引包含所有滿足查詢需要的資料的索引成為覆蓋索引(covering index),也就是所說的不需要回表操作。簡單來說就是將被查詢的字段,建立到聯合索引裡去。
覆蓋索引的定義與注意事項
如果乙個索引覆蓋(包含)了所有需要查詢的字段的值,這個索引就是覆蓋索引。因為索引中已經包含了要查詢的字段的值,因此查詢的時候直接返回索引中的字段值就可以了,不需要再到表中查詢,避免了對主鍵索引的二次查詢,也就提高了查詢的效率。
要注意的是,不是所有型別的索引都可以成為覆蓋索引的。因為覆蓋索引必須要儲存索引的列值,而雜湊索引、空間索引和全文索引等都不儲存索引列值,
另外,當發起乙個被索引覆蓋的查詢(索引覆蓋查詢)時,在explain(執行計畫)的extra列可以看到【using index】的資訊。
覆蓋索引的優點
1.索引條目通常遠小於資料行的大小,因為覆蓋索引只需要讀取索引,極大地減少了資料的訪問量。
2.索引是按照列值順序儲存的,對於io密集的範圍查詢會比隨機從磁碟讀取每一行資料的io小很多。
3.一些儲存引擎比如myisam在記憶體中只快取索引,資料則依賴作業系統來快取,因此要訪問資料的話需要一次系統呼叫,使用覆蓋索引則避免了這一點。
4.由於innodb的聚簇索引,覆蓋索引對innodb引擎下的資料庫表特別有用。因為innodb的二級索引在葉子節點中儲存了行的主鍵值,如果二級索引能夠覆蓋查詢,就避免了對主鍵索引的二次查詢。
1.全表count查詢優化
mysql>
create
table
user(-
> id int(10
)auto_increment,-
> name varchar(30
),-> age tinyint(4
),->
primary
key(id),-
>
)engine
=innodb
charset
=utf8mb4;
例如:select count(age) from user;
使用索引覆蓋優化:建立age欄位索引
create
index idx_age on
user
(age)
;
2.列查詢回表優化前文在描述索引覆蓋使用的例子就是
例如:select name,*** from t where name = 「ls」
使用索引覆蓋:建組合索引idx_age_name(name,***)即可。
3.分頁查詢
例如:select id,age,name from user order by age limit 100,2;
name欄位不是索引,所以在分頁查詢需要進行回表查詢,此時extra為using filesort檔案排序,查詢效能低下。
使用索引覆蓋:建組合索引idx_age_name(age,name)
參考借鑑,致謝!!
傳送門1
傳送門2
MySQL索引,回表,索引覆蓋
多讀多寫多記錄,多學多練多思考。banana.banuit gang 香柚幫 mysql innodb的主鍵索引是簇集索引,也就是索引的葉子節點存的是整個單條記錄的所有字段值,不是主鍵索引的就是非簇集索引,非簇集索引的葉子節點存的是主鍵欄位的值。回表是什麼意思?就是你執行一條sql語句,需要從兩個b...
mysql覆蓋索引與回表
要說回表查詢,先要從innodb的索引實現說起。innodb有兩大類索引,一類是聚集索引 clustered index 一類是普通索引 secondary index innodb的聚集索引 innodb聚集索引的葉子節點儲存行記錄,因此innodb必須要有且只有乙個聚集索引。1.如果表定義了pk...
MySQL 的覆蓋索引與回表
如果表設定了主鍵,則主鍵就是聚簇索引 如果表沒有主鍵,則會預設第乙個not null,且唯一 unique 的列作為聚簇索引 以上都沒有,則會預設建立乙個隱藏的row id作為聚簇索引 innodb的聚簇索引的葉子節點儲存的是行記錄 其實是頁結構,乙個頁包含多行資料 innodb必須要有至少乙個聚簇...