加入收藏 | 设为首页 | 会员中心 | 我要投稿 聊城站长网 (https://www.0635zz.com/)- 智能语音交互、行业智能、AI应用、云计算、5G!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

Mysql索引过长怎么处理

发布时间:2023-08-31 14:38:38 所属栏目:MySql教程 来源:
导读:本文主要给大家介绍Mysql索引过长怎么办,希望可以给大家补充和更新些知识

mysql 索引过长1071-max key length is 767 byte

问题

create table: Specified key was too long; max key length is 767 byt
本文主要给大家介绍Mysql索引过长怎么办,希望可以给大家补充和更新些知识
 
mysql 索引过长1071-max key length is 767 byte
 
问题
 
create table: Specified key was too long; max key length is 767 bytes
 
原因
 
数据库表采用utf8编码,其中varchar(255)的column进行了唯一键索引
 
而mysql默认情况下单个列的索引不能超过767位(不同版本可能存在差异)
 
于是utf8字符编码下,255*3 byte 超过限制
 
解决
 
1  使用innodb引擎;
 
2  启用innodb_large_prefix选项,将约束项扩展至3072byte;
 
3  重新创建数据库;
 
my.cnf配置:
 
default-storage-engine=INNODB
 
innodb_large_prefix=on
 
一般情况下不建议使用这么长的索引,对性能有一定影响;
 
这是网上的一遍文章的解决办法,但是我没有修改成功
 
下面我参考了一些其他的文章并结合自己的操作一步步去确定问题在哪。
 
有同学问到InnoDB的索引长度问题,简单说几个tips。
 
 关于3072
 
 大家经常碰到InnoDB单列索引长度不能超过767bytes,实际上联合索引还有一个限制是3072。
 
Mysql索引过长怎么办
 
Sql代码  收藏代码
 
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。
 
        **   我又参考了上边这篇文章确定了这个最大3072是可以的,那下面我们找方法把它弄成3072.**
 
又参考了一篇文章,终于有点眉目了
 
创建一张表,其中有个varchar 大字段,并且在这个字段上建索引,结果发现MySQL报错:
 
ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.
 
以下为建表语句:
 
create table piratebay(
 
SYS_ID      int ,
 
FILE_NAME   VARCHAR(200),
 
FILE_ID     VARCHAR(30),
 
NUM1        VARCHAR(30),
 
NUM2        VARCHAR(30),
 
MAGNET_LINK VARCHAR(500),
 
PRIMARY KEY (sys_id),
 
KEY         piratebay_n1 (FILE_NAME))
 
engine=innodb;
 
MySQL 环境配置:
 
Server version: 5.6.28-log MySQL Community Server (GPL)
 
Server characterset: utf8mb4
 
Db       characterset: utf8mb4
 
解决办法:
 
(1)查看相关配置并作出如下设置
 
innodb_large_prefix = ON
 
innodb_file_format = Barracuda
 
innodb_file_per_table = ON
 
(2)修改建表语句,加入 row_format=DYNAMIC
 
create table piratebay(
 
SYS_ID      int ,
 
FILE_NAME   VARCHAR(200),
 
FILE_ID     VARCHAR(30),
 
NUM1        VARCHAR(30),
 
NUM2        VARCHAR(30),
 
MAGNET_LINK VARCHAR(500),
 
PRIMARY KEY (sys_id),
 
KEY         piratebay_n1 (FILE_NAME))
 
engine=innodb row_format=dynamic;
 
原因:
 
   MySQL 索引只支持767个字节,utf8mb4 每个字符占用4个字节,所以索引最大长度只能为191个字符,即varchar(191),若想要使用更大的字段,mysql需要设置成支持数据压缩,并且修改表属性 row_format ={DYNAMIC|COMPRESSED}
 
         大家看明白了吧,吧row_formatl类型修改为这两种模式。
 
可以看到row_formatl类型,下面修改类型
 
CREATE TABLE test2 ( id int(11) NOT NULL AUTO_INCREMENT, date varchar(25) DEFAULT NULL, sess_id varchar(255) DEFAULT NULL, keyword varchar(25) NOT NULL, url_n varchar(3) DEFAULT NULL, s_n varchar(3) DEFAULT NULL, select_url varchar(255) DEFAULT NULL, UNIQUE KEY (id,keyword) ) ENGINE=innodb DEFAULT row_format=dynamic;
 
 

(编辑:聊城站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章