[转帖]MySQL创建联合索引报key长度超3072 bytes的[42000][1071]错误

mysql,创建,联合,索引,key,长度,bytes,错误 · 浏览次数 : 0

小编点评

**解决方案:** 1. **调整索引字段长度**: - 修改字段长度,例如 `varchar(255)` 替换为 `varchar(191)`。 - 如果需要,修改索引名称以保持一致性。 2. **使用前缀索引**: - 创建一个包含所有字段名的索引,并使用 `LIKE`运算符在索引中使用该字段名。 - 例如,创建一个索引 `part_of_name`,其值是 `name(10)`。 3. **开启 innodb_large_prefix**: - 该选项允许 MySQL 5.6 及以上版本使用 3072 字节的索引长度,而默认值为 767 字节。 - 将 `innodb_large_prefix` 设置为 `ON` 可以解决索引长度超出限制的问题。 4. **使用前缀索引**: - 创建一个包含所有字段名的索引,并使用 `LIKE`运算符在索引中使用该字段名。 5. **调整 innodb_default_row_format**: - 设置 `innodb_default_row_format` 为 `DYNAMIC` 或 `COMPRESSED`,以允许索引长度超过 3072 字节。 **注意:** - 以上解决方案可能对索引维护和性能产生影响,因此在启用前应该测试它们。 - 在使用前缀索引之前,请确保所有字段名以相同顺序排列。

正文

问题时这样的,我在建表时加了联合索引结果报key长度超过3072个字节了,如下图。

[42000][1071] Specified key was too long; max key length is 3072 bytes

先说解决方案:1.调整索引字段,包括修改字段长度、更换字段;2.使用前缀索引

在MySQL 5.6以及以前的版本,InnoDB引擎默认索引长度不能超过767 bytes,在MySQL 5.5以后支持4个字节的utf8mb4(mb4全称maximun of 4 bytes per multibyte character),也就是说当CHARSET=utf8mb4时varchar最大只能是varchar(191),因为192x4=768大于767了。

可以通过开启innodb_large_prefix让InnoDB引擎默认索引长度达到3072 bytes,在MySQL 5.6默认innodb_large_prefix=OFF,可以通过设置innodb_large_prefix=ON、innodb_file_format=barracuda、innodb_file_per_table=true 且Innodb表的存储格式(row format)为 DYNAMIC 或 COMPRESSED让索引长度达到3072 bytes。

  1. #MySQL 5.6以及以前的版本可执行
  2. set global innodb_large_prefix=1;
  3. set global innodb_file_format=BARRACUDA;

 

 到MySQL 5.7默认innodb_large_prefix=ON,到MySQL 8.0以后直接remove了innodb_large_prefix、innodb_file_format等变量,row format为DYNAMIC或COMPRESSED让索引长度达到3072 bytes,REDUNDANT和COMPACT只有767 bytes,MySQL 8.0默认innodb_default_row_format=DYNAMIC,所以高版本不用动,前提一定要是InnoDB引擎,MyISAM引擎默认是1000 bytes,NDB则不支持。

为什么是767和3072?网上查资料说,767是历史问题,char最大是255,以前设计者以为一个长度255的索引就够用了,以前UTF8最大支持3个字节,256x3-1=767;InnoDB一个page的默认大小是16k,由于是Btree组织,要求叶子节点上一个page至少要包含两条记录,所以一个记录最多不能超过8k,又由于InnoDB的聚簇索引结构,一个二级索引要包含主键索引,因此每个单个索引不能超过4k (极端情况,primay-key和某个二级索引都达到这个限制),由于需要预留和辅助空间,减掉后不能超过3500,取个“整数”即1024bytes*3=3072bytes。

接着说下解决方案,InnoDB引擎默认索引长度最大只能是3072 bytes,对此我想到这两个方案:1.调整索引字段,包括修改字段长度、更换字段;2.使用前缀索引。其中修改字段长度可能会报“[22001][1406] Data truncation: Data too long for column 'xxx' at row N”错。

前缀索引就是用该列的前面部分字符来创建索引,官方给的例子如下:

CREATE INDEX part_of_name ON customer (name(10));

创建前缀索引前我们可以先比较重复率

  1. select 1.0*count(distinct 字段名)/count(*) from 表名;
  2. select 1.0*count(distinct left(字段名, 1))/count(*) from 表名;
  3. select 1.0*count(distinct left(字段名, 2))/count(*) from 表名;
  4. select 1.0*count(distinct left(字段名, 3))/count(*) from 表名;
  5. select 1.0*count(distinct left(字段名, 4))/count(*) from 表名;
  6. ...

最后取结果最接近或等于1的那个,然后添加前缀索引“alter table 表名 add key(字段名(数字));”,其中left函数会返回具有指定长度的字符串的左边部分(LEFT(str, length))。

与[转帖]MySQL创建联合索引报key长度超3072 bytes的[42000][1071]错误相似的内容:

[转帖]MySQL创建联合索引报key长度超3072 bytes的[42000][1071]错误

问题时这样的,我在建表时加了联合索引结果报key长度超过3072个字节了,如下图。 [42000][1071] Specified key was too long; max key length is 3072 bytes 先说解决方案:1.调整索引字段,包括修改字段长度、更换字段;2.使用前缀索

[转帖]mysql中innodb创建表的一些限制

https://www.cnblogs.com/jackssybin/p/16258953.html 1、 背景 在新创建mysql数据表的时候。不太确定表能创建多少个字段,多少个索引。索引多少有限制么?mysql的数据是怎么存储的存在在哪里。 2、基本个数限制 在MySQL5.6.9以后的版本,一

[转帖]MySQL 8.0 Instant Add Column功能解析

https://zhuanlan.zhihu.com/p/408702204 概述 DDL(Data Definition Language)是数据库内部的对象进行创建、删除、修改的操作语言,主要包括:加减列、更改列类型、加减索引等类型。数据库的模式(schema)会随着业务的发展不断变化,如果没有

[转帖]Mysql向表中循环插入数据

如何查看MySQL的当前存储引擎 看你的mysql现在已提供什么存储引擎: mysql> show engines; 看你的mysql当前默认的存储引擎: mysql> show variables like '%storage_engine%'; 创建表 create table per2 (id

【转帖】《MySQL高级篇》四、索引的存储结构

1. 为什么使用索引 假如给数据使用 二叉树 这样的数据结构进行存储,如下图所示 2、索引及其优缺点 2.1 索引概述 2.2 优点 类似大学图书馆建书目索引,提高数据检索的效率,降低 数据库的 IO 成本 这也是创建索引的主要的原因。通过创建唯一索引,可以保证数据库表中每一行 数据的唯一性 (唯一

[转帖]用sysbench压测mysql、postgresql(蟑螂db)对比

mysql: 准备创建表和数据: sysbench --db-driver=mysql --time=10 --threads=10 --report-interval=1 --mysql-host=172.18.44.84 --mysql-port=7999 --mysql-user=zl --m

[转帖]sysbench压测postgresql(mysql同理)

准备创建表和数据:sysbench --db-driver=pgsql --time=1 --threads=1000 --report-interval=5 --pgsql-host=192.168.1.35 --pgsql-port=5001 --pgsql-user=testpgs --pgs

[转帖]Jmeter创建数据库(JDBC)测试-4

上一章节讲述如何建立HTTP请求测试,本章节将介绍使用MySQL数据库驱动程序进行JDBC测试。要使用该驱动程序,必须将其包含的.jar文件(例如mysql-connector-java-XXX-bin.jar)复制到JMeter 的lib目录下(也可以直接在测试计划中导入此jar包) 4.1 添加

[转帖]Redis manager快速启动

2.x 快速启动 系统环境要求 JDK8+, OpenJDK8+ Maven3 Mysql5.7+ 启动命令 在 redis-manager 目录下执行 ./bin/start.sh 准备数据库 系统仅需要创建数据库即可,相关表会在项目启动时自动创建 CREATE DATABASE `redis_m

[转帖]MySQL pid 和 socket 文件说明

2021-10-13 11:595110转载MySQL 1 pid-file文件 MySQL 中的 pid 文件记录的是当前 mysqld 进程的 pid ,pid 亦即 Process ID 。可以通过 pid-file 参数来配置 pid 文件路径及文件名,如果未指定此变量,则 pid 文件默认