首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL COUNT(DISTINCT) 優化:偽鬆散索引掃描技巧

     編輯:MySQL 資料庫相關知識

問題場景

單表 10GB+,統計 UV 查詢:

SELECT COUNT(DISTINCT nick) FROM user_access;

雖有 nick 索引,執行計劃顯示 type=index(全索引掃描),耗時 52.78 秒,造成伺服器抖動。

優化原理:利用索引有序性跳過重複值

索引按 nick 升序儲存。原查詢逐行掃描所有重複 nick;若能「跳躍」至下一個不同值,即為 Loose Index Scan(Oracle 原生支援,MySQL 5.1 未直接支援)。

改寫 SQL 實現偽 Loose Index Scan

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

執行計劃對比

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

核心機制解析

  1. MySQL 內部將 DISTINCT 優化為 GROUP BY
  2. 優化器識別出可利用索引分組,僅掃描每組第一筆(Using index for group-by)
  3. 外層 COUNT(*) 僅統計行數,無需回表

適用條件與避坑

  • ✅ 索引欄位為查詢目標單欄位
  • ✅ 無 WHERE 條件或條件可下推
  • ❌ 複合索引非前導欄位無效
  • ❌ MySQL 8.0+ 已原生支援 Loose Index Scan,可直接用原寫法
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved