萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL COUNT(*) 與 DISTINCT 效率深度研究:MyISAM 快速計數原理與避坑指南

COUNT(*) 極速返回之謎

SELECT COUNT(*) FROM tablename;        -- 秒級返回,即使千萬行
SELECT COUNT(*) FROM tablename WHERE ...; -- 明顯變慢

原因:MyISAM 表在元數據中維護精確行數,無 WHERE 時直接讀取元數據;有 WHERE 必須掃描索引/表過濾。

InnoDB:無精確行數統計,COUNT(*) 始終需掃描(聚簇索引或二級索引),但 8.0+ 並行掃描大幅提速。

DISTINCT 進階用法與陷阱

1. 計算不重複值個數

SELECT COUNT(DISTINCT id) FROM tablename;

2. 返回不重複值列表

SELECT DISTINCT id FROM tablename;

3. 多列 DISTINCT 的語義陷阱

SELECT DISTINCT id, type FROM tablename;
-- 返回 (id, type) 組合不重複的行,而非 id 不重複!

4. 解決「單列去重但保留其他列」

方案 A:GROUP_CONCAT (MySQL 4.1+)

SELECT id, GROUP_CONCAT(type) FROM tablename GROUP BY id;

方案 B:聚合函數併列

SELECT id, type, COUNT(DISTINCT id) FROM tablename GROUP BY id, type;
-- 返回 id 唯一的所有行,附帶計數列

最佳實踐建議

  1. 無 WHERE 計數用 COUNT(*),MyISAM 秒出結果;InnoDB 考慮 SELECT COUNT(id) 走二級索引。
  2. 需去重計數用 COUNT(DISTINCT col),注意大表性能。
  3. 多列去重務必明確語義:DISTINCT col1, col2 = 元組去重。
  4. 「單列去重保留其他列」用 GROUP BY + 聚合函數 或 窗口函數(8.0+)。
copyright © 萬盛學電腦網 all rights reserved