【MySQL】索引长度的一些限制
有同学问到InnoDB的索引长度问题,简单说几个tips。
MySQL的每个单表中所创建的索引长度是有限制的,且对不同存储引擎下的表有不同的限制。
- myisam表,单列索引,最大长度不能超过 1000 bytes,否则会报警,但是创建成功,最终创建的是前缀索引(取前333个字符)。
- myisam表,组合索引,索引长度和不能超过 1000 bytes,否则会报错,创建失败;
- innodb表,单列索引,超过 767 bytes的,给出warning,最终索引创建成功,取前缀索引(取前 255 字符)。
- innodb表,组合索引,各列长度不超过 767 bytes ,如果有超过 767 bytes 的,则给出报警,索引最后创建成功,但是对于超过 767 字节的列取前缀索引,与索引列顺序无关,总和不得超过 3072 ,否则失败,无法创建。
测试:
作者只对mysql innodb 引擎,utf8字符集定义的表做了实际的测试,myisam留给读者
版本:


新建测试表:



组合索引中有大于 767 bytes的字段,产生告警


结合上边两个测试结果,可以看到组合索引长度之和大于 767 bytes并无影响,当有某个字段定义长度大于 767 bytes(1000*3)时,仅产生告警,但不影响创建,超长字段会取前 255 字符作为前缀索引,并且组合索引中字段出现的顺序并无关系。


可以看到,由于每个字段占用255*3, 因此这个索引的大小是3825>3072,报错。
为什么3072
InnoDB一个page的默认大小是 16 k。由于是Btree组织,要求叶子节点上一个page至少包含两条记录(否则就退化链表了)。所以一个记录最多不能超过 8 k。又由于InnoDB的聚簇索引结构,一个二级索引要包含主键索引,因此每个单个索引不能超过 4 k(极端情况,pk和某个二级索引都达到这个限制)。由于需要预留和辅助空间,扣掉后不能超过 3500 ,取个“整数”就是(1024*3)。
单列索引限制
默认情况下,InnoDB 引擎单一字段索引的长度最大为 767 字节,同样的,前缀索引也有同样的限制。当使用 UTF-8 字符集,每一个字符使用 3 字节来存储,767=256*3-1,在 TEXT 或者 VARCHAR 类型的字段上建立一个超过 255 字符数的前缀索引时就会遇到问题。至于为什么字符长度限制在 256 内,我猜是为提高索引效率,应为varchar类型需要额外的字节保留其长度信息,256 就将其限定在一个字节了。但是在5.5以后,开始支持4个字节的uutf8。255×4>767, 于是增加了一个参数叫做innodblargeprefix。这个参数默认值是OFF,当改为ON时,允许列索引最大达到 3072 字节。要求表的 row_format 需要使用 compressed 或者 dynamic。
主要字符集的计算方式:
- latin1 = 1 byte = 1 character
- uft8 = 3 byte = 1 character
- gbk = 2 byte = 1 character
使用前缀索引带来的风险:
INNODB的索引会限制单独Key的最大长度为 767 字节,超过这个长度必须建立小于等于 767 字节的前缀索引。 此外,BLOB和TEXT类型的列只能创建前缀索引。 前缀索引能提高索引建立速度和检索速度,但是下面情况是无法使用前缀索引的:
- 索引覆盖扫描
- 通过索引的排序(order by, group by)
还是在上面的测试表上:


author:bill
2015年 12月 08日
参考
【MySQL】索引长度的一些限制的更多相关文章
- MySQL 索引长度和区分度
首先 索引长度和区分度是相互矛盾的, 索引长度太短,那么区分度就很低,吧索引长度加长,区分度就高,但是索引也是要占内存的,所以我们需要找到一个平衡点: 那么这个平衡点怎么来定? 比如用户表有个字段 ...
- Mysql索引长度和区分度
首先 索引长度和区分度是相互矛盾的, 索引长度太短,那么区分度就很低,吧索引长度加长,区分度就高,但是索引也是要占内存的,所以我们需要找到一个平衡点: 那么这个平衡点怎么来定? 比如用户表有个字段 ...
- MySQL索引长度限制问题
在修改表结构时出现了错误:Specified key was too long;max key length is 1000 bytes. MySQL版本为Server version: 5.1.36 ...
- mysql索引长度
http://blog.csdn.net/qsc0624/article/details/51335632 大家应该知道InnoDB单列索引长度不能超过767bytes,联合索引还有一个限制是长度不能 ...
- MySQL索引长度限制
索引 TextField是不支持建立索引的 MySQL对索引字段长度有限制 innodb引擎的每个索引列长度限制为767字节(bytes),所有组成索引列的长度和不能大于3072字节 myisam引擎 ...
- mysql 索引长度限制
MyISAM存储引擎引键的长度综合不能超过1000字节 InnoDB单列索引长度不能超过767bytes,联合索引还有一个限制是3072
- mysql索引长度的一些限制
一.myisam存储引擎 1. 数据库版本:阿里云RDS MySQL5.1 mysql> select @@version;+-------------------------------+| ...
- mysql 索引长度的限制
myisam表,单列索引,最大长度不能超过 1000 bytes: innodb表,单列索引,最大长度不能超过 767 bytes: utf8 编码时 一个字符占三个字节 varchar 型能建 ...
- 索引长度过长 ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
1.发现问题 今天在修改innodb表的某个列的长度时,报如下错误: alter table test2 modify column id varchar(500); ERROR 1071 (4200 ...
随机推荐
- jQuery弹出层始终垂直居中相对于屏幕或当前窗口
把弹出层的位置设为fixed,设置top:50%,然后获取当前元素的整体的高度height,用获取的高度height/2,设置margin-top:-height/2.即可把当前的弹出层始终垂直居中于 ...
- 获取验证码,60秒倒计时js
<input type="button" id="btn" value="免费获取验证码" /><script type= ...
- Android 中解析 JSON
有什么不懂的可以去官网去看看:www.json.org 在google android中也有关于解析JSON的类库:JsonReader,但是只能在3.0以后的版本中才可以用,在这里我们用google ...
- POJ-1155 TELE (树形DP+分组背包)
题目大意:给一棵带边权的有根树,每个叶子节点有权.边权表示代价,叶子节点的权值代表可以补偿多少代价.问从根节点最多可以到达多少个叶子,使得付出的总代价不大于0. 题目分析:定义状态dp(u,k)表示从 ...
- Python字符串分割
代码如下: [root@localhost test]# cat 3.py #coding=utf-8 ev = """ 1evilxr 2www 3nihao 4evi ...
- 黑马程序员——JAVA基础之常用DOS命令和环境变量的配置
------- android培训.java培训.期待与您交流! ---------- 1.常用dos命令: dir 显示当前文件下目录 ...
- VC++ MFC橡皮筋技术
在MFC下绘制直线,使用橡皮筋技术,可以使直线效果跟随鼠标移动 //OnLButtionDown m_ptOrigin = m_ptEnd = point; //OnMouseMove ...
- OSPF
Ospf OSPF(开放最短路径优先协议)是一种无类内部网关协议(IGP):是一种链路状态路由选择协议: 入门: 可以把整个网络(一个自治系统AS)看成一个王国,这个王国可以分成几个 区(area), ...
- Linux启动新进程的三种方法
程序中,我们有时需要启动一个新的进程,来完成其他的工作.下面介绍了三种实现方法,以及这三种方法之间的区别. 1.system函数-调用shell进程,开启新进程system函数,是通过启动shell进 ...
- 4.Nexus按项目类型分配不同的工厂来发布不同的项目
在[3.发布Maven项目到nexus中]配置了把项目发布到nexus中的方法但是有时候,一个公司会有很多项目[crm,oa,erp]等等的项目.如果把这些项目全部都放到releases或者snaps ...