Mysql 5.6.36 联合索引长度过长

495 阅读1分钟

Mysql 联合索引长度过长

环境:
linux: Red Hat 4.8.5-16
mysql: 5.6.36

表:

show create table parts;
CREATE TABLE `parts` (
  `PART_ID` bigint(20) NOT NULL,
  `CREATE_TIME` int(11) NOT NULL,
  `LAST_ACCESS_TIME` int(11) NOT NULL,
  `PART_NAME` varchar(767) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `SD_ID` bigint(20) DEFAULT NULL,
  `TBL_ID` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`PART_ID`),
  KEY `PARTITIONS_N49` (`TBL_ID`),
  KEY `PARTITIONS_N50` (`SD_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

关键参数及默认值:

show variables like '%per_table%';
show variables like '%large_prefix%';
show variables like '%file_format%';

image.png

image.png

image.png

  1. innodb_large_prefix=1 启用此选项可允许使用或行格式的表的索引键前缀长度超过 767 字节(最多 3072 个字节)。
    创建此类表还需要选项值 innodb_file_format=梭子鱼和 innodb_file_per_table=true。

  2. innodb_file_per_table=1 启用innodb_file_per_table后,将在每个表的文件表空间中创建表。禁用时,将在系统表空间中创建表。

  3. innodb_file_format=Barracuda
    为每表文件表空间启用文件格式。

image.png

innodb参数参考:dev.mysql.com/doc/refman/…

  1. ROW_FORMAT = DYNAMIC;
    DYNAMIC格式:当行太长时,将选择最长的列进行页外存储,直到聚集索引记录适合B树页。
    行格式参考:dev.mysql.com/doc/refman/…

-- 新增索引长度超限

mysql> alter table parts add unique key UNIQUEPARTITION (PART_NAME,TBL_ID);
ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

-- 修改的办法

-- 1 修改表行格式为动态行
alter table parts ROW_FORMAT = DYNAMIC;
-- 2 给字段缩长度
ALTER TABLE parts CHANGE PART_NAME PART_NAME VARCHAR(760) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

参考:
dev.mysql.com/doc/refman/…
www.cnblogs.com/wilburxu/p/…