首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL DISTINCT 優化技巧:偽 Loose Index Scan 實現 9 倍加速

     編輯:MySQL 綜合教學

MySQL DISTINCT 優化技巧:偽 Loose Index Scan 實現 9 倍加速

問題場景

SELECT COUNT(DISTINCT nick) FROM user_access_xx_xx;
  • 單表 10GB+,nick 有索引
  • 執行計劃:type=index(全索引掃描)
  • 執行時間:**52.78 秒**,造成伺服器抖動

原理分析

索引按 (nick, other_column) 升序排列。原查詢從第一個 nick 掃到最後,中間大量重複值逐行讀取。

Oracle 有 Loose Index Scan**(跳躍掃描)**,直接跳過重複值;MySQL 5.1 不支援,需手工模擬。

索引掃描示意圖

改寫方案:子查詢先 DISTINCT,外層 COUNT

SELECT COUNT(*) FROM (
    SELECT DISTINCT nick FROM user_access
) t;

執行計劃對比

指標 原始寫法 優化寫法
執行時間 52.78 秒 5.81 秒(快 9 倍)
Extra Using index Using index for group-by**
掃描行數 19,546,123 2,124,695

原理解析

  • MySQL 將 DISTINCT 內部轉為 GROUP BY
  • 子查詢 SELECT DISTINCT nick 觸發 Using index for group-by:優化器利用索引分組,**每個 nick 僅掃描一次**
  • 外層 COUNT(*) 僅統計結果集行數,極快

適用條件與限制

  • ✅ 適用:單欄位 DISTINCT、該欄位有索引、資料量大、重複度高
  • ❌ 不適用:多欄位 DISTINCT a,b、無索引、資料量小
  • 📌 MySQL 8.0+ 已支援真正的 Loose Index Scan,但此技巧在舊版本依然有效

💡 一句話心法:大表 COUNT(DISTINCT col) 慢時,改成 SELECT COUNT(*) FROM (SELECT DISTINCT col FROM tbl) t 利用 Using index for group-by 跳躍掃描。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved