mysql索引长度怎么设置_mysql存储与性能权衡

来源:这里教程网 时间:2026-02-28 20:52:51 作者:

MySQL 索引长度由字段类型和字符集决定,不能直接“设置”

MySQL 不提供类似

INDEX LENGTH = 100
这样的语法来手动指定索引长度。所谓“索引长度”,本质是 MySQL 对索引列实际存储字节数的计算结果,它取决于:字段定义(如
VARCHAR(255)
)、字符集(如
utf8mb4
)、是否为前缀索引
。InnoDB 要求单个索引列(或前缀)长度不超过 767 字节(
innodb_large_prefix=OFF
时),或 3072 字节(
ON
且行格式为
DYNAMIC
COMPRESSED
)。

什么时候必须用前缀索引?

当字段是长文本(如

VARCHAR(1000)
)且使用
utf8mb4
字符集时,完整索引可能超限:1000 × 4 = 4000 字节 > 3072 → 报错
ERROR 1071 (42000): Specified key was too long
。此时只能截取前缀:

CREATE INDEX idx_title ON articles (title(191));
——
utf8mb4
下 191 字符 ≈ 191 × 4 = 764 字节,安全
选择前缀长度要兼顾区分度:
SELECT COUNT(DISTINCT LEFT(title, 191)) / COUNT(*) FROM articles;
接近 1 才有效
避免对短字段(如
VARCHAR(50)
)加前缀——没意义,还削弱查询能力(
WHERE title = 'xxx'
无法走索引)

CHAR/VARCHAR 的定义长度不等于索引长度

很多人误以为

VARCHAR(255)
就会建出 255 字符的索引。实际取决于你是否显式指定前缀:

ALTER TABLE t ADD INDEX (name);
→ 对
VARCHAR(255)
字段,若字符集为
utf8mb4
,则默认尝试索引全部 255 字符 → 255×4=1020 字节 → 在老版本或配置下直接失败
ALTER TABLE t ADD INDEX (name(100));
→ 明确只索引前 100 字符,长度为 400 字节
CHAR(10)
字段无论内容多短,索引长度固定为 10 × 字符字节数(
utf8mb4
下恒为 40 字节)

影响性能的关键不是“长度数字”,而是区分度与覆盖范围

索引太短(如

name(5)
)会导致大量哈希碰撞,B+ 树底层节点重复值多,扫描行数暴增;索引太长(如
content(1000)
)不仅占更多 Buffer Pool,还会让二级索引页更少容纳记录,降低缓存效率。实操建议:

SHOW INDEX FROM table_name;
查看
Sub_part
列:非 NULL 表示用了前缀索引,数值即前缀长度
SELECT data_length / index_length FROM information_schema.tables WHERE table_name = 't';
辅助判断索引膨胀是否异常
对 JSON 字段或超长 URL,优先考虑生成哈希字段(
url_hash CHAR(32) AS (MD5(url)) STORED
)再建索引,比前缀更可控

真正难的是在业务模糊匹配需求(如

LIKE '%关键词%'
)和索引物理限制之间找平衡点——这时候前缀索引往往只是权宜之计,该上全文索引或 Elasticsearch 就别硬扛。

相关推荐