索引是對特定列通過特定算法 (默認 B+Tree) 排序後的數據結構,將掃描行數從 O(N) 降至 O(log N)。哈希索引適用於等值查詢,B+Tree 支持範圍與排序。
| 欄位 | 含義 | 優化重點 |
|---|---|---|
type | 訪問類型:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL | 至少達到 range,最好 ref 或 eq_ref |
possible_keys | 可能用到的索引 | 為 NULL 需檢查 WHERE 條件列 |
key | 實際使用的索引 | NULL 表示全表掃描 |
key_len | 索引鍵長度,越短越好 | 檢查是否用到組合索引最左列 |
rows | 預估掃描行數 (InnoDB 不準) | 核心指標,優化目標是降低 rows |
Extra | 額外信息:Using index (覆蓋索引佳) / Using where / Using temporary、Using filesort (需優化) | 避免 filesort/temporary |
(a,b,c),查詢 a=1 AND b=2 AND c>3 用到 a,b;c>3 為範圍查詢,匹配停止,d 無法用到索引。count(DISTINCT col)/count(*) > 0.1 (JOIN 字段建議 > 0.1)。性別/狀態等低區分度列不宜建索引。from_unixtime(create_time) = '...' 失效,改為 create_time = unix_timestamp('...')。(a),需 (a,b) 直接 ALTER TABLE ... ADD INDEX (a,b) 覆蓋舊索引。INDEX (name, city, age) 等價於擁有 (name,city,age), (name,city), (name) 三個索引。最左前綴原則:缺左列則不可用,如 WHERE city='x' AND age=20 不走索引。
長字符串列 (如 VARCHAR(255)) 可只索引前 N 字符:INDEX (title(10))。選擇 N 使區分度 > 0.31 (黃金值)。
SELECT COUNT(DISTINCT LEFT(title,10))/COUNT(*) FROM t; -- >0.31 可建
ALTER TABLE t ADD INDEX idx_title_10 (title(10));
WHERE col + 10 = 30; -- 索引列參與運算
WHERE LEFT(date,4) < 1990; -- 索引列用函數
WHERE name LIKE '%abc%'; -- 前導通配符
WHERE name REGEXP '...'; -- 正則不走索引
WHERE char_col = 123; -- 字符串列比較數字 (隱式轉換)
WHERE a=1 OR b=2; -- OR 導致全表掃描 (除非兩列都有索引且優化器選擇 index_merge)
LEFT JOIN 以小表驅動大表,減少驅動表掃描行數。