使用 Navicat 為 MySQL 資料表建立索引時,常遇到 Specified key was too long; max key length is 1000 bytes 錯誤(錯誤碼 1071)。本文解析根本原因並提供多種實戰解決方案。
MySQL 索引鍵總長度不能超過 1000 字節。字段長度計算公式:
latin1:1 字節 = 1 字符gbk:2 字節 = 1 字符utf8:3 字節 = 1 字符utf8mb4:4 字節 = 1 字符複合索引總長度 = Σ(字段定義長度 × 字符集字節數) ≤ 1000 字節。
CREATE UNIQUE INDEX unique_record ON reports (report_name, report_client, report_city); -- 字段均為 VARCHAR(200) -- GBK 編碼:(200+200+200) × 2 = 1200 > 1000 → 報錯 -- 解決:將 report_city 改為 VARCHAR(100) → (200+200+100)×2 = 1000 ✓ -- UTF8 編碼:(200+200+200) × 3 = 1800 > 1000 → 仍報錯
將超長字段(如 URL、長文本)透過 MD5/SHA1 轉為固定長度雜湊值(32/40 字符),建立索引於雜湊字段,原字段保留供查詢顯示。
ALTER TABLE reports ADD COLUMN report_city_hash CHAR(32); UPDATE reports SET report_city_hash = MD5(report_city); CREATE INDEX idx_city_hash ON reports (report_city_hash);
分析業務唯一性約束,若多字段組合中某字段可由其他字段唯一推導,則從索引中移除該字段,降低總長度。
若字段內容僅包含基本拉丁字符,可將字段字符集從 utf8 改為 gbk 或 latin1,單字節數減半或更多。前提:現有數據必須能被目標字符集完整表示,否則會導致數據截斷或亂碼。
對長字符串字段僅索引前 N 個字符:
CREATE INDEX idx_name_prefix ON reports (report_name(50), report_client(50));
注意:前綴索引會降低選擇性,需評估查詢性能影響。