知用网
霓虹主题四 · 更硬核的阅读氛围

varchar字段建索引注意什么

发布时间:2026-01-19 14:31:44 阅读:194 次

varchar字段建索引注意什么

在MySQL开发中,给varchar字段加索引是家常便饭。但别以为加上就完事了,实际使用中一不小心就会踩坑。比如你给一个存用户邮箱的字段加了索引,结果查询还是慢得像蜗牛,问题可能就出在索引策略上。

字段长度别太长

varchar本身是变长字符串,但如果字段设计得太长,比如VARCHAR(1000),直接对它建B+树索引,会导致索引体积膨胀。MySQL的索引页默认16KB,单个索引条目不能太大,否则一页能存的键值就少,树就得更高,IO次数自然上升。

解决办法是使用前缀索引。比如邮箱字段,通常前10~20位就有足够区分度,可以只索引前缀:

ALTER TABLE users ADD INDEX idx_email_prefix(email(20));

这样既能节省空间,又能提升查询效率。不过得提前分析下数据,确保前N位的重复率够低,不然会拖垮性能。

注意字符集和排序规则

同一个字符串在不同字符集下占用空间不同。UTF8MB4下,一个汉字占4字节,如果字段用了UTF8MB4又建了索引,那实际存储的索引键会比想象中大不少。比如一个VARCHAR(50)的中文名字段,在索引里最多可能占200字节。

同时,排序规则(如utf8mb4_general_ci、utf8mb4_bin)也会影响索引行为。不区分大小写的规则会让等值查询更“宽松”,但也可能让优化器难以利用索引做范围扫描。

避免在表达式中使用索引字段

就算你给name字段建了索引,下面这种写法也用不上:

SELECT * FROM users WHERE UPPER(name) = 'ZHANGSAN';

因为索引保存的是原始值,不是UPPER后的结果。函数一套,索引就废了。正确做法是保持字段“裸奔”出现在条件左边。

考虑是否需要唯一约束

如果是手机号、身份证这类业务上唯一的字段,直接建唯一索引。既能保证数据干净,又能让查询走索引直达数据页。唯一索引的另一个好处是,InnoDB插入时会先查是否存在,命中索引就能快速拒绝重复写入。

ALTER TABLE users ADD UNIQUE INDEX uk_phone(phone);

联合索引中的位置安排

如果和其他字段组联合索引,比如(name, age),记得把筛选性强的放前面。但若name是varchar且很长,即便筛选性强,也可能导致整个联合索引变重。这时候得权衡:是拆成单独索引,还是调整顺序,甚至考虑生成列加索引。

比如地址字段很少用于精确查询,反而age过滤性更好,那或许应该把age放前面,或者干脆不让varchar长字段进联合索引。

监控索引使用情况

建完索引别撒手不管。通过EXPLAIN看查询是否真的走了索引,也可以查information_schema.STATISTICS确认索引存在且统计信息更新了。长时间不用的索引及时清理,避免拖累写入性能。