mysql> CREATE TABLE `tb` (
-> `a` varchar(255) DEFAULT NULL,
-> `b` varchar(255) DEFAULT NULL,
-> `c` varchar(255) DEFAULT NULL,
-> `d` varchar(255) DEFAULT NULL,
-> `e` varchar(255) DEFAULT NULL,
-> KEY `a` (`a`,`b`,`c`,`d`,`e`)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes
可以看到,由于每个字段占用255*3, 因此这个索引的大小是3825>3072,报错。
为什么3072
我们知道InnoDB一个page的默认大小是16k。由于是Btree组织,要求叶子节点上一个page至少要包含两条记录(否则就退化链表了)。
所以一个记录最多不能超过8k。
又由于InnoDB的聚簇索引结构,一个二级索引要包含主键索引,因此每个单个索引不能超过4k (极端情况,pk和某个二级索引都达到这个限制)。
由于需要预留和辅助空间,扣掉后不能超过3500,取个“整数”就是(1024*3)。
单列索引限制

上面有提到单列索引限制767,起因是256×3-1。这个3是字符最大占用空间(utf8)。但是在5.5以后,开始支持4个字节的uutf8。255×4>767, 于是增加了一个参数叫做 innodb_large_prefix。
这个参数默认值是OFF。当改为ON时,允许列索引最大达到3072。
可以看到默认行为是建表成功,报一个warning,并且将长度阶段为255。
注意要生效需要加row_format=compressed或者dynamic 。
如果确实需要在单个很大的列上创建索引,或者需要在多个很大的列上创建联合索引,而又超过了索引的长度限制,解决办法是在建索引时限制索引prefix的大小:
例如:create index yarn_app_result_i4 on yarn_app_result (flow_exec_id(100), another_column(50));
这样,在创建索引时就会限制使用的每个列的最大长度。如上的例子中,在创建联合索引时,最多使用列flow_exec_id中前100个字符创建索引,最多使用another_column中前
50个字符创建索引。这样子,就可以避免索引长度过大的问题。

最后,我想说一句。我们在设计数据库时,最好不要在一个可能包含很长字符串的列上创建索引,尤其是当这个列中的字符串都很长时。如果在这类列上创建了索引,那么在创建索引时以及根据索引查询时,都会浪费很多时间在计算和存储上。有经验的设计人员应该不会这样设计数据库。

[转]MySQL InnoDB引擎索引长度受限怎么办的更多相关文章

  1. mysql InnoDB引擎索引超过长度限制

    组合索引长度之和大于 767 bytes并无影响,当有某个字段定义长度大于 767 bytes(1000*3)时,仅产生告警,但不影响创建,超长字段会取前 255 字符作为前缀索引,并且组合索引中字段 ...

  2. mysql优化-------Myisam与innodb引擎,索引文件的区别

    Myisam与innodb引擎,索引文件的区别: innodb的次索引指向对主键的引用. myisam的次索引和主索引都指向物理行. myisam一行一行的插入,会产生一行一行的文件,磁盘上有数据文件 ...

  3. 巧用MySQL InnoDB引擎锁机制解决死锁问题(转)

    该文会通过一个实际例子中的死锁问题的解决过程,进一步解释innodb的行锁机制 最近,在项目开发过程中,碰到了数据库死锁问题,在解决问题的过程中,笔者对MySQL InnoDB引擎锁机制的理解逐步加深 ...

  4. Mysql InnoDB引擎下 事务的隔离级别

    mysql InnoDB 引擎下事物学习 建表user CREATE TABLE `user` ( `uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT, ...

  5. MySQL InnoDB引擎B+树索引简单整理说明

    本文出处:http://www.cnblogs.com/wy123/p/7211742.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...

  6. 数据库索引使用数据结构及算法, 及MySQL不同引擎索引实现

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  7. mysql innodb 引擎

    innodb 引擎 一.概述 InnoDB 是一个用的比较广泛的存储引擎,因为它支持事物和外键,还有不错的效率;我们先看看官方教程怎么说; 我们先读一下, 对于上面的文档, 对一个InnoDB的表首先 ...

  8. MySQL innodb引擎下根据.frm和.ibd文件恢复表结构和数据

    记录通过.frm和.ibd文件恢复数据到本地 .frm文件:保存了每个表的元数据,包括表结构的定义等: .ibd文件:InnoDB引擎开启了独立表空间(my.ini中配置innodb_file_per ...

  9. [MySQL]InnoDB引擎的行锁和表锁

    1.行锁和表锁 在mysql 的 InnoDB引擎支持行锁,与Oracle不同,mysql的行锁是通过索引加载的,即是行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表扫描, 行锁则 ...

随机推荐

  1. 微信小程序支付之代码详解

    微信小程序自带的一套规则,类似vue语法,但是好多功能都集成在api中,给了很多初学者轮子,所以首先要熟悉这些api,忘记可照官网继续开发 这里主要说下微信小程序的支付,原理类似上篇介绍的公众网页支付 ...

  2. 项目中UX设计1到2的设计提升总结

  3. C#操作Word的+ CKEditor 輸出成Word文件(包含圖案上傳)

    C#操作Word 参考博文: C#操作word类文件 https://www.cnblogs.com/walking/p/3571068.html C#中的Office操作专栏(21) http:// ...

  4. Linux 下工作用户及环境

    交叉工具的安装 工具链的编译过程请参考第三部分. 1. 下载交叉工具 2.95.3 下载地址:ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cro ...

  5. w - 显示已经登录的用户以及他们在做什么

    总览 (SYNOPSIS) w - [husfV] [user] 描述 (DESCRIPTION) w 显示 系统中 当前用户 的 信息, 以及 他们 的 进程. 第一行 中 依次 显示 当前时间, ...

  6. hadoop–JobTracker 相关

    JobTracker 内部使用三层表示: JobInProgress: 跟踪和监控作业运行状态的对象.每个Job分成了多个Task.并为每个Task创建一个TaskInProgress跟踪和监控其运行 ...

  7. margin与padding

    1.不加内边距的div: <div style="width:150px; height:150px; ">    <div style="width: ...

  8. 小程序学习三 一切的开始app() 小程序的注册

    现在打开 app.js //app.js App({ onLaunch(options) { //小程序初始化 // console.log("小程序初始化", options) ...

  9. 在命令行窗口中输入EOF

    在Windows中,要输入EOF前,先回车换行,再ctrl+z,在回车,即可.

  10. 面向对象oop 和类

    面向对象与面向过程的区别 面向对象:面向对象的思维模式说白了就是分类思维模式.思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考.最后,才对某个分类下的细节进行面向过程的思索 自我理解(领 ...