ALTER TABLE article ADD INDEX ind_article_url(url);
-- Warning: Specified key was too long; max key length is 767 bytes
url VARCHAR(512),字元集 GBK(雙位元組)→ 1024 bytes > 767 限制。MySQL 自動建立前綴索引 url(383)(766 bytes)。
| 字元集 | 單字元位元組 | 最大索引字元數 |
|---|---|---|
| latin1 | 1 | 767 |
| GBK | 2 | 383 |
| UTF-8 | 3 | 255 |
選擇性 = COUNT(DISTINCT prefix) / COUNT(*),越接近 1 越好。
-- 全欄位選擇性
SELECT COUNT(DISTINCT url)/COUNT(*) FROM article; -- 0.0750
-- 不同前綴長度選擇性
SELECT
COUNT(DISTINCT LEFT(url,76))/COUNT(*) AS url_76,
COUNT(DISTINCT LEFT(url,77))/COUNT(*) AS url_77,
...
COUNT(DISTINCT LEFT(url,85))/COUNT(*) AS url_85
FROM article;
| 長度 | 選擇性 |
|---|---|
| 76 | 0.0747 |
| 77 | 0.0748 |
| 78 | 0.0749 |
| 79 | 0.0749 |
| 80 | 0.0749 |
| 81 | 0.0749 |
| 82 | 0.0749 |
| 83 | 0.0749 |
| 84 | 0.0749 |
| 85 | 0.0750 |
**85 字元即達到全欄位選擇性**,無需用 383 字元。建立索引:
ALTER TABLE article ADD INDEX ind_article_url(url(85));
⚠️ 無法用於 ORDER BY 和 GROUP BY:
EXPLAIN SELECT id, url, deleted FROM article GROUP BY url;
-- type=ALL, Extra=Using temporary; Using filesort
需全欄位索引才能支援排序/分組。
Specified key was too long 警告 → 需用前綴索引ORDER BY/GROUP BY,若需則考慮其他方案(如 hash 索引、應用層處理)💡 小索引不僅省空間、減記憶體,**更能提升快取命中率與掃描速度**。