詳解MYSQL索引失效問題排查

目錄

一、快速定位索引失效的步驟

1. 使用?EXPLAIN?分析執行計劃詳解Mysql的Explain語句

2. 確認索引是否存在

3. 檢查查詢條件是否符合索引規則

二、常見索引失效場景及解決方法?

1. 索引列參與計算或函數

2. 隱式類型轉換

3. 使用?LIKE?以通配符開頭

4. 使用?OR?連接非索引列?

5. 索引選擇性過低

6.?聯合索引順序錯誤

7. 使用?!=?或?<>?操作符

8.?IS NULL?或?IS NOT NULL?條件

9. 多個索引ORDER BY?順序不一致

10.? 全文索引的誤用

三、高級排查工具

1. 開啟慢查詢日志

2. 使用?OPTIMIZER_TRACE?分析優化器決策

3. 強制使用索引測試

四、總結


一、快速定位索引失效的步驟

1. 使用?EXPLAIN?分析執行計劃詳解Mysql的Explain語句

EXPLAIN SELECT * FROM users WHERE age = 25 AND name = 'John';

重點關注以下字段:

  • type:若顯示?ALL(全表掃描)或?index(全索引掃描),可能索引未生效。

  • key:實際使用的索引名稱,若為?NULL?表示未使用索引。

  • rows:預估掃描的行數,數值過大說明索引可能未生效。

  • Extra:若出現?Using filesort?或?Using temporary,可能索引未被用于排序或分組。

2. 確認索引是否存在

SHOW INDEX FROM users;  -- 查看表的索引信息

確保查詢涉及的列(尤其是?WHEREJOINORDER BY?中的列)已創建索引。

3. 檢查查詢條件是否符合索引規則

  • 最左前綴原則:聯合索引?(a, b, c)?必須按順序使用,跳過中間列會導致后續列無法使用索引。

    WHERE a=1 AND c=3;  -- 僅使用到 a 列的索引,c 列無法生效
  • 范圍查詢阻斷索引:范圍查詢(><BETWEEN)后的列無法使用索引。

    WHERE a>10 AND b=20;  -- 僅 a 列使用索引,b 列無法生效

二、常見索引失效場景及解決方法?

1. 索引列參與計算或函數

  • 失效示例

    SELECT * FROM users WHERE YEAR(create_time) = 2023;  -- 對索引列使用函數
    SELECT * FROM users WHERE age + 10 > 30;            -- 對索引列進行運算
  • 優化方法:改寫為直接使用索引列。

    SELECT * FROM users WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31';

2. 隱式類型轉換

  • 失效示例

    -- 假設 phone 是 VARCHAR 類型,但傳入數字
    SELECT * FROM users WHERE phone = 13800138000;  -- 字符串轉數字導致索引失效
  • 優化方法:確保數據類型一致。

    SELECT * FROM users WHERE phone = '13800138000';

3. 使用?LIKE?以通配符開頭

  • 失效示例

    SELECT * FROM users WHERE name LIKE '%John%';  -- 前導通配符導致索引失效
  • 優化方法:盡量使用右通配符。

    SELECT * FROM users WHERE name LIKE 'John%';  -- 可能使用索引

4. 使用?OR?連接非索引列?

  • 失效示例

    -- 假設 age 有索引,address 無索引
    SELECT * FROM users WHERE age = 25 OR address = 'Beijing';  -- 全表掃描
  • 優化方法:改用?UNION?拆分查詢。

    SELECT * FROM users WHERE age = 25 
    UNION 
    SELECT * FROM users WHERE address = 'Beijing';

5. 索引選擇性過低

  • 問題現象:索引列的值重復率過高(如性別字段),MySQL 可能放棄使用索引。

  • 優化方法:刪除低選擇性索引,或結合其他列創建聯合索引。

    ALTER TABLE users ADD INDEX idx_gender_age (gender, age);

6.?聯合索引順序錯誤

  • 問題現象:聯合索引?(a, b, c),但查詢未按最左前綴順序使用,導致索引部分失效。

  • 失效示例

    -- 索引 (a, b, c)
    SELECT * FROM table WHERE b = 2 AND a = 1;  -- 正常使用索引(優化器自動調整順序)
    SELECT * FROM table WHERE a = 1 AND c = 3;  -- 僅用到 a 列索引,c 未生效
    SELECT * FROM table WHERE b = 2;            -- 索引完全失效(未使用最左列 a)
  • 優化方法

    • 調整查詢條件順序,確保按最左前綴匹配。

    • 根據高頻查詢場景,設計合理的聯合索引順序。

7. 使用?!=?或?<>?操作符

  • 問題現象:非等值查詢(如?!=NOT IN)可能導致索引失效。

  • 失效示例

    SELECT * FROM users WHERE age != 25;       -- 可能全表掃描
    SELECT * FROM orders WHERE status NOT IN (1, 2);  
  • 優化方法

    • 改寫為等值查詢或范圍查詢:

      SELECT * FROM users WHERE age < 25 OR age > 25;  -- 仍可能失效,需結合其他條件
    • 若數據分布傾斜,強制使用索引(需測試驗證):

      SELECT * FROM users FORCE INDEX(idx_age) WHERE age != 25;

8.?IS NULL?或?IS NOT NULL?條件

  • ?問題現象:索引列上使用?IS NULL?或?IS NOT NULL?可能導致索引失效。

  • 失效示例

    SELECT * FROM users WHERE phone IS NULL;      -- 可能全表掃描
  • 優化方法:若 NULL 值較少,添加條件冗余字段:

    ALTER TABLE users ADD COLUMN is_phone_null TINYINT(1) DEFAULT 0;
    CREATE INDEX idx_phone_null ON users(is_phone_null);
    SELECT * FROM users WHERE is_phone_null = 1;

    9. 多個索引ORDER BY?順序不一致

    • ?問題現象:排序字段順序與索引順序不匹配,導致無法利用索引排序。

    • 失效示例

      -- 索引 (a, b)
      SELECT * FROM table WHER ORDER BY a ASC, b DESC;  -- 2個索引順序不一致導致失效
      
    • 優化方法:調整聯合索引順序,同升同降。

      SELECT * FROM table WHER ORDER BY a ASC, b ASC;  同升同降
      

    10.? 全文索引的誤用

    • ?問題現象:錯誤使用?LIKE?或?MATCH AGAINST?導致索引失效。

    • 失效示例

      -- 未使用全文索引
      SELECT * FROM articles WHERE content LIKE '%database%';  
      
    • 優化方法

      • 對文本搜索需求改用全文索引(FULLTEXT Index)。

      • 避免在全文索引列上混合使用?LIKE?和?MATCH

        SELECT * FROM articles WHERE MATCH(content) AGAINST('database');

    三、高級排查工具

    1. 開啟慢查詢日志

    -- 配置 my.cnf
    slow_query_log = 1
    slow_query_log_file = /var/log/mysql/slow.log
    long_query_time = 2   -- 記錄執行超過2秒的SQL

    通過慢日志定位高頻低效 SQL。

    2. 使用?OPTIMIZER_TRACE?分析優化器決策

    SET optimizer_trace = 'enabled=on';
    SELECT * FROM users WHERE age = 25;  -- 執行你的查詢
    SELECT * FROM information_schema.optimizer_trace;  -- 查看優化器選擇索引的過程

    3. 強制使用索引測試

    SELECT * FROM users FORCE INDEX (idx_age) WHERE age = 25;  -- 強制使用索引

    對比強制索引前后的執行時間,判斷優化器是否選錯索引。

    四、總結

    • 核心原則:索引失效的本質是?無法快速定位數據范圍

    • 關鍵檢查點

      • 避免對索引列進行計算或函數操作。

      • 確保查詢條件符合最左前綴原則。

      • 注意隱式類型轉換和通配符使用。

    • 工具輔助EXPLAIN、慢查詢日志、OPTIMIZER_TRACE?是排查利器。

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/news/907184.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/news/907184.shtml
    英文地址,請注明出處:http://en.pswp.cn/news/907184.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    在 springboot3.x 使用 knife4j 以及常見報錯匯總

    目錄 引言&#xff1a; 引入依賴&#xff1a; 配置文件&#xff1a; 過濾靜態資源&#xff1a; 增強模式&#xff1a; 便捷地址訪問&#xff1a; 常見問題&#xff1a; 注解使用實例&#xff1a; &#x1f4c4; ?文檔參考地址?&#xff1a; SpringBoot 3.x 結合 …

    【C/C++】環形緩沖區:高效數據流轉核心

    文章目錄 1 核心結構與原理1.1 組成1.2 內存布局1.3 關鍵操作 2 實現細節與優化2.1 滿/空狀態的判斷2.2 多線程安全&#xff08;無鎖實現&#xff09;2.3 性能優化 3 典型應用場景4 代碼示例5 優缺點6 對比7 進階 環形緩沖區&#xff08;Ring Buffer&#xff09;&#xff0c;又…

    功耗僅4W!迷你服務器黑豹X2(Panther X2)卡刷、線刷刷入Armbian(ubuntu)系統教程

    功耗僅4W&#xff01;迷你服務器黑豹X2&#xff08;Panther X2&#xff09;卡刷、線刷刷入Armbian&#xff08;ubuntu&#xff09;系統教程 前言 前段時間逛海鮮市場的時候留意到一個礦渣盒子&#xff0c;黑豹x2&#xff0c;又是一個類似迅雷賺錢寶這樣的挖礦項目已經gg的定制…

    【Elasticsearch】更新操作原理

    Elasticsearch 的更新操作&#xff08;如 _update 和 _update_by_query&#xff09;在底層實現上有一些復雜的原理&#xff0c;這些原理涉及到 Elasticsearch 的數據存儲機制、索引機制以及事務日志&#xff08;Translog&#xff09;的使用。以下是 Elasticsearch 更新操作的主…

    【C++】紅黑樹的實現

    目錄 前言 一、紅黑樹的概念 二、紅黑樹的實現 三、紅黑樹的查找 四、紅黑樹的驗證 五、紅黑樹的刪除 總結 前言 本文講解紅黑樹&#xff0c;主要講解插入部分的實現&#xff0c;建議在理解了AVL樹的旋轉后再來學習紅黑樹&#xff0c;因為紅黑樹也涉及旋轉&#xff0c;并…

    IPv4地址的主要配置項介紹

    1. IPv4 主要配置項 (1) IP 地址&#xff08;IP Address&#xff09; 作用&#xff1a;唯一標識網絡中的設備&#xff08;如 192.168.1.100&#xff09;。分類&#xff1a; 靜態 IP&#xff1a;手動配置&#xff0c;適用于服務器、打印機等固定設備。動態 IP&#xff08;DHCP…

    nginx 基于IP和用戶的訪問

    nginx的下載 yum install nginx.x86_64 -y 啟動服務 systemctl enable --now nginx.service 查看服務目錄 [rootwebserver ~]# rpm -ql nginx /usr/bin/nginx-upgrade /usr/lib/systemd/system/nginx.service /usr/share/man/man3/nginx.3pm.gz /usr/share/man/man8/nginx…

    Debian操作系統全面解析:從起源到應用

    Debian 操作系統全面解析:從起源到應用 在開源操作系統的廣袤天地中,Debian 占據著極為重要的地位。它憑借自身諸多突出特性,吸引了全球無數用戶與開發者的目光,從個人桌面應用到大型服務器部署,從普通辦公場景到專業科研領域,Debian 都展現出了強大的適應性與可靠性,為…

    【springMVC】springMVC學習系列一:springMVC的組件

    系列文章目錄 前言 spring mvc 它解決了什么問題呢&#xff1f; 1.URL映射 2. 表單參數映射 3. 調用目標Control 4. 數據模型映射 5. 視圖解析 6. 異常處理 上述解決在spring mvc 中都體現在如下組件當中 HandlerMapping&#xff1a; url與控制器的映謝 HandlerAdapter&#…

    【Vue Vapor Mode :技術突破與性能優化的可能性】

    Vue Vapor Mode &#xff1a;技術突破與性能優化的可能性 前言 作為一名有著Vue 2經驗和Vue 3經驗的開發者&#xff0c;你一定深刻體會過Vue從Options API到Composition API的演進&#xff0c;也感受過Vue 3在性能上相比Vue 2的顯著提升。現在&#xff0c;Vue團隊正在開發一個…

    MySQL數據庫零基礎入門教程:從安裝配置到數據查詢全掌握【MySQL系列】

    第1章&#xff1a;認識MySQL 1.1 什么是MySQL&#xff1f; MySQL是一種開源的關系型數據庫管理系統&#xff08;RDBMS&#xff09;&#xff0c;由瑞典MySQL AB公司開發&#xff0c;現由Oracle公司維護。它使用結構化查詢語言&#xff08;SQL&#xff09;進行數據庫的管理和操…

    AXI3、AXI4 和 AXI5 的詳細差異對比

    AXI3、AXI4 和 AXI5 的詳細差異對比 摘要&#xff1a;AXI (Advanced eXtensible Interface) 是 ARM 公司提出的高性能片上總線協議&#xff0c;廣泛用于 SoC (System on Chip) 設計中&#xff0c;以實現高效的數據傳輸和系統互連。AXI 協議隨著版本的迭代不斷演進&#xff0c;從…

    向量數據庫該如何選擇?Milvus 、ES、OpenSearch 快速對比:向量搜索能力與智能檢索引擎的應用前景

    ? 1.milvus VS ES Milvus 的亮點 功能性&#xff1a;Milvus 不僅支持基本的向量相似性搜索&#xff0c;還支持稀疏向量、批量向量、過濾搜索和混合搜索功能等高級功能。 靈活性&#xff1a;Milvus 支持多種部署模式和多個 SDK&#xff0c;所有這些都在一個強大的集成生態系…

    SQL進階之旅 Day 4:子查詢與臨時表優化

    文章標題 【SQL進階之旅 Day 4】子查詢與臨時表優化 文章內容 開篇&#xff1a;SQL進階之旅的第4天 在“SQL進階之旅”系列中&#xff0c;第4天的主題是子查詢與臨時表優化。這是SQL開發中不可或缺的一部分&#xff0c;尤其在處理復雜查詢時&#xff0c;合理使用子查詢和臨…

    Python學習(2) ----- Python的類型

    在 Python 中&#xff0c;一切皆對象&#xff0c;每個對象都有類型。下面是 Python 中的常見內置類型分類和示例&#xff1a; &#x1f7e1; 1. 數字類型&#xff08;Numeric Types&#xff09; 類型說明示例int整數5, -42float浮點數3.14, -0.5complex復數1 2j a 10 …

    跨協議協同智造新實踐:DeviceNet-EtherCAT網關驅動汽車焊接裝配效能躍遷

    在汽車制造領域&#xff0c;機器人協作對于提升生產效率與產品質量至關重要。焊接、裝配等關鍵環節&#xff0c;需要機器人與各類設備緊密配合。JH-DVN-ECT疆鴻智能的devicenet從站轉ethercat主站協議網關&#xff0c;成為實現這一高效協作的得力助手&#xff0c;尤其是在連接歐…

    nginx之proxy_buffering的作用

    Nginx 的緩沖機制是為了讓后端能更快釋放資源&#xff0c;而不是卡在慢客戶端上&#xff0c;從而提升整體性能和并發能力。 現實中客戶端和后端服務器之間的傳輸速率可能差異很大。Nginx 的緩沖機制正是為了解決這個不匹配問題。 假設沒有緩沖&#xff08;即 proxy_buffering…

    數據庫相關問題

    1.保留字 1.1錯誤案例&#xff08;2025/5/27&#xff09; 報錯&#xff1a; java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near condition, sell…

    GO 語言進階之 進程 OS與 編碼,數據格式轉換

    更多個人筆記見&#xff1a; github個人筆記倉庫 gitee 個人筆記倉庫 個人學習&#xff0c;學習過程中還會不斷補充&#xff5e; &#xff08;后續會更新在github上&#xff09; 文章目錄 進程信息OS操作基本例子 編碼相關HASH 哈希Base64 encoding 基礎64編碼 數據格式轉換和處…

    如何用Spring Cache實現對Redis的抽象

    我們在進行Java項目開發時候&#xff0c;經常會用到Redis緩存例如數據庫里的一些信息、手機驗證碼之類的&#xff0c;正常寫法就會像去連mysql一樣&#xff0c;這種硬編碼的方式肯定是非常不合適的。 Autowireprivate UserMapper userMapper;Autowireprivate StringCommand str…