【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 ...
随机推荐
- 卷积神经网络的初步理解LeNet-5(转)
深度神经网路已经在语音识别,图像识别等领域取得前所未有的成功.本人在多年之前也曾接触过神经网络.本系列文章主要记录自己对深度神经网络的一些学习心得. 第二篇,讲讲经典的卷积神经网络.我不打算详细描述卷 ...
- Js的引用赋值与传值赋值
要说js的赋值方式时首先要说明js的数值类型:基本类型和引用类型. 1.基本类型 基本的数据类型有:undefined,boolean,number,string,null. 基本类型存放在栈区,访问 ...
- android之官方下拉刷新组件SwipeRefreshLayout
1.setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener):设置手势滑动监听器. 2.setProgressBackgr ...
- 使用ASP.NET web API创建REST服务(三)
本文档来源于:http://www.cnblogs.com/madyina/p/3390773.html Creating a REST service using ASP.NET Web API A ...
- hdu3861 强连通+最小路径覆盖
题意:有 n 个点,m 条边的有向图,需要将这些点分成多个块,要求:如果两点之间有路径能够互相到达,那么这两个点必须分在同一块:在同一块内的任意两点相互之间至少要有一条路径到达,即 u 到达 v 或 ...
- meta是什么意思?
META标签,是HTML语言head区的一个辅助性标签.在几乎所有的page里,我们都可以看 到类似下面这段html代码: -------------------------------------- ...
- 【NOIP2008】双栈排序
感觉看了题解还是挺简单的,不知道当年chty同学为什么被卡了呢么久--所以说我还是看题解了 原题: Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将 ...
- Python小白好教程
提供一些Python的基础教程. Crossin的编程教师:网址:http://crossincode.com/home/ 廖雪峰的官方网站 网址:http://www.liaoxuefeng.com ...
- 使用支持向量机训练mnist数据
# encoding: utf-8 import numpy as np import matplotlib.pyplot as plt import cPickle import gzip clas ...
- httplib
可爆破目录 import httplib import urllib def sendhttp(): data = urllib.urlencode({'@number': 12524, '@type ...