问题描述原因
今日线上数据库增加索引出现了索引过长导致报如下信息错误
报错信息:ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
报错信息:ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes
解决方案
因为MySQL的InnoDB存储引擎的表存在一系列的限制条件,其中比较常见的一种是表的字段索引长度限制,该限制与参数innodb_large_prefix相关。
原因分析
导致上面报错的原因是由于InnoDB表的索引长度限制,在MySQL5.6版本后引入了参数innodb_large_prefix可以解决这个问题。该参数控制是否允许单列的索引长度超过767字节,有ON和OFF两个取值:
ON :Innodb表的行记录格式是Dynamic或Compressed的前提下,单列索引长度上限扩展到3072个字节
OFF:Innodb表的单例索引长度最多为767个字节,索引长度超出后,主键索引会创建失败,辅助索引会被截断成为前缀索引
解决方案
使用前缀索引,减少字段索引长度
设置MySQL的全局参数innodb_large_prefix=ON,将InnoDB表的索引长度上限扩大到3072个字节
测试过程
说明
字段varchar(N)中的N是指字符的长度,不是字节数,需要结合字符集换算得出字节数。例如:utf8字符集一个字符占3个字节,若单列索引限制767,则最大可以支持N=255.
总结建议
总结
innodb表的单列索引长度最大字节数是767字节,辅助索引超出会被截断,主键索引超出不会截断直接报错导致建表失败
innodb表的联合索引中每个字段的最大字节数是767字节,并且要求联合索引的总长度不超过3072字节
主键索引不允许被截断,辅助索引可以被截断
设置参数innodb_large_prefix=ON只能把单列索引长度扩大到3072字节,联合索引总长度的上限不变,仍然是3072个字节
建议
在数据库迁移和数据库版本升级的过程中,需要对齐源库和目标库的innodb_large_prefix参数取值,否则可能导致建表失败
在设计数据库表结构的过程中,对于一个可能包含很长字符串的列上创建索引时尽量使用前缀索引
作者:运维老许
联系方式:strive120620@163.com
微信公众号:Linux必修之路
声明1:本站部分资源收集自互联网,仅供个人学习交流,如不慎侵犯了您的权益,请联系我,我将尽快处理!
声明2:本文版权归作者,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利!