探索MySQL的InnoDB索引失效

快乐的总统95發表於2024-10-06

MySQL 8+

InnoDB

-

序章

索引失效,發生在 已經建立索引,但是,查詢(SELECT)時沒有用到建立的(預期會用到)索引的情況下。

失效原因有兩個方面:

1、建立索引的方式錯誤

需要弄清楚 欄位的 #區分度(極其重要) 這個概念。選擇 區分度高 的建立索引。

2、某些SELECT語句不支援 使用索引

注意,除了索引失效,導致 慢查詢 的另一個重要原因是——沒有建立索引,沒有在 建立表 的時候第一時間建立索引

本文探索 MySQL使用時常見的索引失效情況,做個彙總。

通義千問

問題:InnoDB:索引失效會在什麼情況下發生

回答:

在 InnoDB 儲存引擎中,索引失效 是指 查詢最佳化器 決定不使用已存在的索引,而是 選擇全表掃描 或 其他方式來執行查詢

以下是一些常見的索引失效情況:

1)選擇性低的索引

原因:如果索引的選擇性很低(即索引列的重複值很多),MySQL 可能會選擇不使用該索引,因為全表掃描可能更快。

#區分度

2)使用 OR 運算子

原因:當查詢條件中包含 OR 運算子時,如果 OR 連線的條件不能使用同一個索引,MySQL 可能會選擇不使用索引。

3)使用函式或表示式

原因:在索引列上使用函式或表示式會導致索引失效,因為 MySQL 無法直接使用索引進行查詢。

4)使用 LIKE 模糊查詢

原因:如果 LIKE 模糊查詢的字首是萬用字元(如 %),索引將失效。

5)資料型別不匹配

原因:如果查詢條件中的資料型別與索引列的資料型別不匹配,MySQL 可能會選擇不使用索引。

6)使用 NOT 運算子

原因:使用 NOT 運算子(如 != 或 <>)時,MySQL 可能會選擇不使用索引,因為這些運算子通常會導致全表掃描。

7)使用 IN 運算子

原因:如果 IN 運算子中的值列表非常大,MySQL 可能會選擇不使用索引。

8)索引列上有大量 NULL 值

原因:如果索引列中有大量 NULL 值,MySQL 可能會選擇不使用該索引。

9)複合索引的使用不當

原因:如果複合索引的前導列沒有出現在查詢條件中,MySQL 可能會選擇不使用該複合索引。

10)表統計資訊不準確

原因:如果表的統計資訊不準確,MySQL 的查詢最佳化器可能會做出錯誤的決策,導致索引失效。

11)使用 LIMIT 時

原因:在某些情況下,使用 LIMIT 時,MySQL 可能會選擇不使用索引,特別是當 LIMIT 的偏移量很大時。

12)使用 JOIN 時

原因:在複雜的 JOIN 查詢中,如果 JOIN 條件不使用索引,MySQL 可能會選擇不使用索引。

解決方法

1、最佳化查詢條件:確保查詢條件儘可能精確,避免使用函式、表示式和萬用字元。
2、使用合適的索引:為查詢條件中的列建立合適的索引,特別是複合索引。
3、定期更新統計資訊:使用 ANALYZE TABLE 命令定期更新表的統計資訊。
4、避免使用 SELECT *:只選擇需要的列,減少資料傳輸量。
5、使用 EXPLAIN 分析查詢:使用 EXPLAIN 命令分析查詢計劃,確保索引被正確使用。

注,大家可以自行去提問。

參考資料#2

補充了2條:

13)資料表過度索引:太多

文中提到,索引太多,可能導致 查詢最佳化器 選擇錯亂。

14)資料表過度龐大

文中提到,資料表太大時,索引的效果減弱了。

文中提到,可以使用 分割槽(PARTITION BY)、分片(ShardingSphere 等工具) 解決該問題。

或許,還有 分庫,還有 使用 其它大資料儲存工具。

小結

基本的 索引失效 大概就這些了,足夠平時開發使用了。

進一步探索:TODO

1、分割槽、分表、分庫 的索引如何建立?

2、MySQL 的 一些叢集方案中怎麼建立索引?這涉及到 大資料方面使用 MySQL 了吧?不太懂。

---END---

本文連結:

https://www.cnblogs.com/luo630/p/18448905

參考資料

1、通義千問

2、MySQL索引失效及避免策略:最佳化查詢效能的關鍵

作者:糜終

2024-09-30

https://developer.aliyun.com/article/1615655

3、

ben釋出於部落格園

ben釋出於部落格園

相關文章