MySQL索引優(yōu)化之回表
在MySQL數(shù)據(jù)庫(kù)中,回表是一個(gè)與索引查詢相關(guān)的重要概念,通常指當(dāng)使用索引查詢數(shù)據(jù)時(shí),僅通過索引無法獲取所需的全部字段信息,需要再次訪問數(shù)據(jù)表(聚簇索引)以獲取完整數(shù)據(jù)的過程
一、回表的基本概念
索引的本質(zhì)
MySQL中的索引(如B+樹索引)是一種數(shù)據(jù)結(jié)構(gòu),用于快速定位數(shù)據(jù)。非聚簇索引(普通索引)存儲(chǔ)的是索引鍵值和對(duì)應(yīng)的主鍵值,而聚簇索引(通?;谥麈I)直接存儲(chǔ)行的完整數(shù)據(jù)。回表的定義
當(dāng)查詢語(yǔ)句通過非聚簇索引找到匹配的主鍵值后,需要根據(jù)主鍵值再次查詢聚簇索引(即數(shù)據(jù)表),以獲取其他字段的數(shù)據(jù),這個(gè)過程稱為回表。
二、回表的發(fā)生場(chǎng)景
1. 查詢字段不在索引中
-- 示例:表user有索引idx_name(姓名),但查詢需要年齡字段 SELECT age FROM user WHERE name = 'name';
步驟:
- 通過
idx_name
索引找到姓名為“張三”的主鍵值。 - 根據(jù)主鍵值回表查詢聚簇索引,獲取
age
字段。
2. 索引覆蓋不完整
若查詢字段部分在索引中,部分不在,仍需回表:
-- 示例:索引idx_name_age(姓名, 年齡),但查詢還需要id字段 SELECT id, name, age FROM user WHERE name = 'name';
- 索引包含
name
和age
,但id
需通過主鍵回表獲取。
3. 使用非覆蓋索引的范圍查詢
-- 示例:索引idx_age(年齡),查詢年齡>18的用戶姓名 SELECT name FROM user WHERE age > 18;
- 每個(gè)滿足條件的
age
對(duì)應(yīng)的主鍵都需要回表獲取name
。
三、回表的性能影響
優(yōu)點(diǎn)
- 利用索引快速定位數(shù)據(jù),避免全表掃描,提升查詢效率。
缺點(diǎn)
- 回表需要多次I/O操作(索引查詢+表查詢),若回表次數(shù)過多(如大量數(shù)據(jù)命中索引),會(huì)導(dǎo)致性能下降。
- 例如:當(dāng)查詢返回10萬條記錄時(shí),回表10萬次可能比直接全表掃描更慢。
四、如何避免或優(yōu)化回表
1. 覆蓋索引(覆蓋查詢)
讓查詢所需的所有字段都包含在索引中,避免回表:
-- 創(chuàng)建覆蓋索引:包含name和age CREATE INDEX idx_name_age ON user(name, age); -- 查詢時(shí)無需回表 SELECT name, age FROM user WHERE name = 'name';
2. 復(fù)合索引的合理設(shè)計(jì)
根據(jù)查詢條件,將常用字段組合成復(fù)合索引:
-- 常用查詢:WHERE name LIKE '張%' AND age > 18 CREATE INDEX idx_name_age ON user(name, age);
3. 減少返回字段
只查詢必要的字段,避免獲取無用數(shù)據(jù):
-- 錯(cuò)誤示例:查詢所有字段 SELECT * FROM user WHERE name = 'name'; -- 優(yōu)化:只查詢需要的字段 SELECT id, name FROM user WHERE name = 'name';
4. 利用覆蓋索引優(yōu)化COUNT查詢
-- 優(yōu)化前:COUNT(*)需回表統(tǒng)計(jì) SELECT COUNT(*) FROM user WHERE age > 18; -- 優(yōu)化后:用覆蓋索引中的字段替代 SELECT COUNT(age) FROM user WHERE age > 18;
5. 分析執(zhí)行計(jì)劃(EXPLAIN)
通過EXPLAIN
查看查詢是否觸發(fā)回表:
EXPLAIN SELECT name FROM user WHERE age > 18; -- 重點(diǎn)關(guān)注: -- 1. type=range/index:索引使用情況 -- 2. Extra=Using index:是否為覆蓋索引(無回表) -- 3. Extra=Using where:是否需要回表
五、聚簇索引與回表的關(guān)系
- 聚簇索引存儲(chǔ)完整數(shù)據(jù),因此通過聚簇索引查詢(如
WHERE id=1
)無需回表。 - 非聚簇索引必須通過主鍵回表,因?yàn)槠渲淮鎯?chǔ)索引鍵和主鍵值。
六、總結(jié)
回表是MySQL索引查詢的常見機(jī)制,合理利用覆蓋索引和優(yōu)化索引設(shè)計(jì)可減少回表次數(shù),提升查詢性能。在實(shí)際開發(fā)中,應(yīng)根據(jù)業(yè)務(wù)查詢場(chǎng)景,針對(duì)性地設(shè)計(jì)索引,平衡索引空間和查詢效率。
到此這篇關(guān)于MySQL索引優(yōu)化之回表的文章就介紹到這了,更多相關(guān)MySQL 回表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
docker下mysql 8.0.20 安裝配置方法圖文教程
這篇文章主要介紹了docker下mysql 8.0.20 安裝配置方法圖文教程,文中安裝步驟介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05MySQL5.6 GTID模式下同步復(fù)制報(bào)錯(cuò)不能跳過的解決方法
搭建虛擬機(jī)centos6.0, mysql5.6.10主從復(fù)制,死活不同步,搞了一整天找到這篇文章終于OK了,特分享一下,需要的朋友可以參考下2020-04-04MySQL無GROUP BY直接HAVING返回空的問題分析
這篇文章主要介紹了MySQL無GROUP BY直接HAVING返回空的問題分析,學(xué)習(xí)MYSQL需要注意這個(gè)問題2013-11-11MySQL中查看數(shù)據(jù)庫(kù)安裝路徑的方法
有時(shí)候在我們開發(fā)的過程中并不一定記得數(shù)據(jù)庫(kù)的安裝路徑,比如要查看mysql 數(shù)據(jù)庫(kù)的安裝目錄在哪里,這里就為大家分享一下2021-03-03