主键UID优化:等长CHAR(35)与不等长VARCHAR(35)性能对比
VARCHAR(35) 和 CHAR(35) 作为主键的性能对比
针对你10万行MySQL表的场景,两种存储方式的性能差异主要体现在这几个方面:
存储与空间效率
- CHAR(35):不管UID实际长度是19还是35位,每条记录的主键字段都会占用固定35字节(字母数字在utf8mb4下是1字节/字符)。短UID补全后多出来的16字节完全是浪费,10万行就是1.6MB的冗余空间。更关键的是InnoDB的聚簇索引叶子节点绑定整行数据,冗余空间会导致索引页能容纳的条目减少,查询时需要更多IO操作,拖慢性能。
- VARCHAR(35):只存储实际长度的字符,再加上1字节的长度标识(因为长度≤255)。19位UID占20字节,35位占36字节,平均下来比CHAR(35)省不少空间。索引页能塞更多条目,缓存命中率更高,IO次数更少。
索引性能
- 聚簇索引影响全局:InnoDB的二级索引叶子节点会存储主键值,CHAR(35)的二级索引每条都占35字节,VARCHAR(35)的二级索引平均仅28字节左右。更小的二级索引意味着占用更少内存,缓存命中率更高,查询速度更快。
- 等值查询差异不大:如果只是主键的等值查询(比如
WHERE uid = 'xxx'),两者的查找速度几乎没区别,MySQL都能快速定位到目标行。
写入与预处理开销
- CHAR(35):写入时不需要处理长度,但得先把短UID补全到35位——不管在应用层还是数据库层做这个补全,都多了一步预处理操作,虽然开销不大,但属于没必要的额外工作。
- VARCHAR(35):写入时只需要记录实际长度,这个开销可以忽略,而且不用做补全,流程更简洁。
最终建议
优先用VARCHAR(35)当主键。它的空间优势会直接转化为更好的缓存效率和更少的IO,在数据量增长后(比如超过百万行),这种差异会更明显。CHAR(35)的固定长度优势对于字母数字字符串来说几乎没用,反而带来空间浪费和额外的预处理步骤。
(注:以上分析基于主流的InnoDB引擎,如果你用的是MyISAM,差异会小很多,但InnoDB是当前MySQL的默认推荐引擎。)
内容的提问来源于stack exchange,提问作者Louis D.
相关产品推荐
相关产品推荐

