MySQL索引失效的原因及問題排查
更新時間:2024年04月26日 10:40:18 作者:山腳ice
MySQL索引失效是指在查詢數(shù)據(jù)時,MySQL數(shù)據(jù)庫無法有效地使用索引來提高查詢性能,導致查詢速度變慢或者索引無效的情況,本文給大家介紹了MySQL中什么情況下會出現(xiàn)索引失效?以及如何排查索引失效?,需要的朋友可以參考下
1-引言:什么是MySQL的索引失效?(What、Why)
1-1 索引失效定義
- 在MySQL中,索引是用來加快檢索數(shù)據(jù)庫記錄的一種數(shù)據(jù)結構。
- 索引失效指的是在進行查詢操作時,本應該使用索引來提升查詢效率的場景下,數(shù)據(jù)庫沒有利用索引,而是采用了全表掃描的方式,這會大大增加查詢時間和系統(tǒng)負擔。
1-2 為什么排查索引失效
排查索引失效的原因是至關重要的,主要有以下方面:
- 1. 提高查詢效率:索引的主要目的是加快數(shù)據(jù)檢索速度。當索引失效時,數(shù)據(jù)庫系統(tǒng)可能退回到更慢的查詢方法,如全表掃描,這會顯著增加查詢時間和降低整體性能。
- 2. 降低服務器負載:使用索引可以顯著減少數(shù)據(jù)庫處理查詢所需處理的數(shù)據(jù)量,從而減少CPU使用率和IO讀寫。如果索引失效,數(shù)據(jù)庫必須加載更多數(shù)據(jù),這會增加服務器的負載和資源消耗。
2- 索引失效的原因及排查(How)
2-1 索引失效的情況
- 以以下的學生信息表舉例
CREATE TABLE `student_info` ( `student_id` int(11) NOT NULL AUTO_INCREMENT, `student_name` varchar(50) NOT NULL, `student_age` int(11) DEFAULT NULL, `enrollment_date` datetime DEFAULT NULL, PRIMARY KEY (`student_id`), UNIQUE KEY `student_name` (`student_name`), KEY `student_age` (`student_age`), KEY `enrollment_date` (`enrollment_date`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- 表的索引情況:
- 總結來說,表
student_info
有四個字段上定義了索引:- 一個主鍵索引
student_id
- 一個唯一索引
student_name
- 以及兩個普通索引
student_age
和enrollment_date
。
- 一個主鍵索引
① 索引列參與計算
- 正常的通過 age 去做查詢
- 走的是 student_age 的索引
explain select * from student_info where student_age=21;
- 如果索引列參與了計算進行查詢
- 索引失效
explain select * from student_info where student_age+1 =21;
- 如果不是對列進行計算,而是對列等號右側的值進行計算,結果還是走索引的。
② 對索引列進行函數(shù)操作
- 正常的查詢——>走索引
explain select * from student_info where enrollment_date = '2022-09-04 08:00:00';
- 如果對查詢的字段加上函數(shù)操作時,索引失效
explain select * from student_info where YEAR(enrollment_date) = 2022;
③ 查詢中使用了 OR 兩邊有范圍查詢 > 或 <
- 正常情況查詢,查詢使用
student_name
索引
explain select * from student_info where student_name='Helen' and student_age>15;
- 如果使用了 OR 進行查詢,兩邊包含范圍查詢 > 或 <
- 此時索引失效
explain select * from student_info where student_name='Helen' or student_age>15;
- 如果沒有范圍查詢下使用 OR 還是正常走索引
explain select * from student_info where student_name='Helen' or student_age=18;
④ like 操作:以 % 開頭的 like 查詢
- 以 % 開頭的 LIKE 查詢比如 LIKE ‘%abc’;;
⑤ 不等于比較 !=
- 在MySQL中
!=
比較有可能會導致不走索引,但如果對 id 進行 != 比較,是有可能走索引的。 !=
比較是否走索引,與索引的選擇、數(shù)據(jù)分布情況有關,不單是由于查詢包含!=
而引起的。
⑥ order by
- 如果使用 order by 時,表中的數(shù)據(jù)量很小,數(shù)據(jù)庫會直接在內(nèi)存中進行排序,而不使用索引
⑦ 使用 IN
- 使用
IN
的時候,有可能走索引,也有可能不走索引。當在IN
的取值范圍比較大的時候有可能會導致索引失效,走全表掃描(NOT IN
和IN
的失效場景相同)。
2-2 索引失效的排查
使用 explain 排查
- 和 MySQL 慢查詢的排查類似,使用 Explain 語句來進行排查。
需要關注的字段:type、key、extra
- 我們可以根據(jù) key、type、extra 來判斷一條語句是否走了索引。
- 一般走索引的情況 :
- key 值不為 null
- type 值應該為 ref、eq_ref、range、const 這幾個
- extra 的話如果是 NULL,或者 using indedx,using index condition 都是可以的
索引失效情況
- 如果一條語句出現(xiàn)了
type
值為all
、key 為null
,extra = Using where
此時是索引失效了
此時就需要排查索引失效的原因
索引是否符合最左前綴匹配
查詢語句出現(xiàn)以上 7 種情況
3- 總結:索引失效知識點小結
MySQL中什么情況下會出現(xiàn)索引失效?如何排查索引失效?
回答
:::info
MySQL中索引失效的情況有
- 比如聯(lián)合索引在查詢的過程中不符合最左前綴原則,此時聯(lián)合索引會失效
- 查詢的語句 索引列 進行計算,此時會使得索引失效
- 查詢的語句 對索引列進行了函數(shù)操作,比如利用了
**YEAR()**
函數(shù)
- 查詢的語句 對索引列進行了函數(shù)操作,比如利用了
- 查詢語句中 包含
**OR**
,且OR
兩側有范圍查詢 也就是**>**
或**<**
此時索引會失效
- 查詢語句中 包含
- 查詢語句中 使用了
**like**
且**like**
中存在 以**%**
開頭的匹配,此時索引會失效
- 查詢語句中 使用了
- 查詢語句中 使用了
**!=**
進行比較,但這種情況也和數(shù)據(jù)的分布情況有關系,
- 查詢語句中 使用了
- 當數(shù)據(jù)表中的數(shù)據(jù)較少,使用
**order by**
的時候,可能會不走索引直接在內(nèi)存中進行排序
- 當數(shù)據(jù)表中的數(shù)據(jù)較少,使用
- 當使用
**IN**
** **時候取值范圍比較大的時候有可能會導致索引失效
- 當使用
索引失效的排查
- ① 使用 Explain 對 SQL 語句進行排查
- 需要 關注的字段有
**type**
、**key**
、**extra**
- 如果一條語句出現(xiàn)了
type
值為all
、key 為null
,extra = Using where
此時是索引失效了
此時就需要排查索引失效的原因,是否存在以上情況
以上就是MySQL索引失效的原因及問題排查的詳細內(nèi)容,更多關于MySQL索引失效的資料請關注腳本之家其它相關文章!
相關文章
LNMP下使用命令行導出導入MySQL數(shù)據(jù)庫的方法
這篇文章主要介紹了LNMP下使用命令行導出導入MySQL數(shù)據(jù)庫的方法,需要的朋友可以參考下2016-09-09mysql installer web community 5.7.21.0.msi安裝圖文教程
這篇文章主要為大家詳細介紹了mysql installer web community 5.7.21.0.msi,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-09-09MySQL中count()和count(1)有何區(qū)別以及哪個性能最好詳解
count是一個函數(shù),用來統(tǒng)計數(shù)據(jù),但是count函數(shù)傳入的參數(shù)有很多種,比如count(1)、count(*)、count(字段)等,下面這篇文章主要給大家介紹了關于MySQL中count()和count(1)有何區(qū)別以及哪個性能最好的相關資料,需要的朋友可以參考下2022-08-08