有同学问到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类型的列只能创建前缀索引。 前缀索引能提高索引建立速度和检索速度,但是下面情况是无法使用前缀索引的:

  1. 索引覆盖扫描
  2. 通过索引的排序(order by, group by)

还是在上面的测试表上:

author:bill

2015年 12月 08日

参考

  1. mysql索引长度的一些限制
  2. 关于InnoDB索引长度限制的tips

【MySQL】索引长度的一些限制的更多相关文章

  1. MySQL 索引长度和区分度

    首先  索引长度和区分度是相互矛盾的, 索引长度太短,那么区分度就很低,吧索引长度加长,区分度就高,但是索引也是要占内存的,所以我们需要找到一个平衡点: 那么这个平衡点怎么来定? 比如用户表有个字段 ...

  2. Mysql索引长度和区分度

    首先  索引长度和区分度是相互矛盾的, 索引长度太短,那么区分度就很低,吧索引长度加长,区分度就高,但是索引也是要占内存的,所以我们需要找到一个平衡点: 那么这个平衡点怎么来定? 比如用户表有个字段 ...

  3. MySQL索引长度限制问题

    在修改表结构时出现了错误:Specified key was too long;max key length is 1000 bytes. MySQL版本为Server version: 5.1.36 ...

  4. mysql索引长度

    http://blog.csdn.net/qsc0624/article/details/51335632 大家应该知道InnoDB单列索引长度不能超过767bytes,联合索引还有一个限制是长度不能 ...

  5. MySQL索引长度限制

    索引 TextField是不支持建立索引的 MySQL对索引字段长度有限制 innodb引擎的每个索引列长度限制为767字节(bytes),所有组成索引列的长度和不能大于3072字节 myisam引擎 ...

  6. mysql 索引长度限制

    MyISAM存储引擎引键的长度综合不能超过1000字节 InnoDB单列索引长度不能超过767bytes,联合索引还有一个限制是3072

  7. mysql索引长度的一些限制

    一.myisam存储引擎 1. 数据库版本:阿里云RDS MySQL5.1 mysql> select @@version;+-------------------------------+| ...

  8. mysql 索引长度的限制

    myisam表,单列索引,最大长度不能超过 1000 bytes: innodb表,单列索引,最大长度不能超过 767 bytes: utf8 编码时   一个字符占三个字节 varchar  型能建 ...

  9. 索引长度过长 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 ...

随机推荐

  1. centos 服务器操作

     CENTOS下创建FTP登录用户 yum install vsftpd2.启动/重启/关闭vsftpd服务器[root@localhost ftp]# /sbin/service vsftpd re ...

  2. This application failed to start because it could not find or load the Qt platform plugin “windows”错误解决方法

    这是一个困扰我很久的问题,关于Qt下生成的exe文件在没有安装Qt的机器上无法运行的问题.Qt是编写C++图形界面的一个很好工具,比MFC来的直观.可是,Qt的安装却是一个让人头疼的事情.早在上个学期 ...

  3. JavaWeb学习记录(十五)——浏览器Cookie禁用后的处理

    IE禁用Cookie方式:

  4. linux笔记_磁盘分区

    一.分区的意义 1.不同操作系统往往不可以同时装载在同一个分区,分区解决了不同操作系统装载在同一个物理硬盘的兼容性问题 2.机械硬盘盘片外圈读写速度相对内圈要快,分区可以把常用数据限制在读写速度较快的 ...

  5. 奇怪的电梯(HDU1548) (Dijkstra)或者(BFS)

    问题 E: 奇怪的电梯 时间限制: 1 Sec  内存限制: 64 MB提交: 35  解决: 16[提交][状态][讨论版] 题目描述 有一天桐桐做了一个梦,梦见了一种很奇怪的电梯.大楼的每一层楼都 ...

  6. kuangbin_ShortPath O (LightOJ 1074)

    这是什么鬼OJ啊都没见过害的我还交错语言CE了一发摔 想着懒得重写了直接把上一题的dij改了改就交了 然后RE 反应过来这题有负环 想着怎么标记负环同时不直接结束spfa 看了别人的代码感叹了一下我还 ...

  7. 关于正则表达式处理textarea里的换行

    将textarea里的内容存入数据库时,会自动将回车换行符过滤成空格,也会将多个空格转换成一个空格,即:将\n等换成 “  ”存入数据库 因此为了将内容从数据库中按照原来格式读出写入到html 就必须 ...

  8. /bin/rm: Argument list too long解決方法

    rm.cp.mv是unix下面常用到的檔案處理指令,當我們需要刪除大量的log檔案,如果檔案數太多就會出現此訊息[/bin/rm: Argument list too long]解決方式如下: 例如要 ...

  9. mysql学习之-字符集选定,修改。

    基础概念:字符(Character)是指人类语言中最小的表义符号.例如'A'.'B'等:编码(Encoding)是指给定一系列字符,对每个字符赋予一个数值,用数值来代表对应的字符.例如,我们给字符'A ...

  10. 在AndroidStudio中引入SlidingMenu第三方库的步骤

    步骤一:        在GitHub上下载库文件     步骤二:         在需要引入库的项目中导入一个Moudle,如下图:     步骤三:         将下载后的Slidingme ...