mysql 索引 too long_mysql 联合索引 too long 错误

If you’ve ever tried to add an index that includes a long varchar column to an InnoDB table in MySQL, you may have seen this error:

ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

The character limit depends on the character set you use. For example if you use latin1 then the largest column you can index is varchar(767) , but if you use utf8 then the limit isvarchar(255) . There is also a separate 3072 byte limit per index. The 767 byte limit is per column, so you can include multiple columns (each 767 bytes or smaller) up to 3072 total bytes per index, but no column longer than 767 bytes. (MyISAM is a little different. It has a 1000 byte index length limit, but no separate column length limit within that).

One workaround for these limits is to only index a prefix of the longer columns, but what if you want to index more than 767 bytes of a column in InnoDB?

In that case you should consider using innodb_large_prefix, which was introduced in MySQL 5.5.14 and allows you to include columns up to 3072 bytes long in InnoDB indexes. It does not affect the index limit, which is still 3072 bytes as quoted in the manual :

The InnoDB internal maximum key length is 3500 bytes, but MySQL itself restricts this to 3072 bytes. This limit applies to the length of the combined index key in a multi-column index.

Read on for details and examples about innodb_large_prefix.

Here are a few pre-requisites for using innodb_large_prefix:

At the database level you have to use innodb_file_format=BARRACUDA

The default file format is still Antelope for backwards compatibility, and the default row format is COMPACT.

You can set both innodb_file_format and innodb_large_prefix dynamically, but you should also set them in my.cnf so they survive a restart.

Here’s an example. If I try to create this table with innodb_large_prefix disabled I get an error:

mysql> create table if not exists utf8_test (-> day date not null,-> product_id int not null,-> dimension1 varchar(500) character set utf8 collate utf8_bin not null,-> dimension2 varchar(500) character set utf8 collate utf8_bin not null,-> unique index unique_index (day, product_id, dimension1, dimension2)-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

If I enable innodb_large_prefix I can create the table successfully:

mysql> set global innodb_file_format = BARRACUDA;Query OK, 0 rows affected (0.00 sec)mysql> set global innodb_large_prefix = ON;Query OK, 0 rows affected (0.00 sec)mysql> create table if not exists utf8_test (-> day date not null,-> product_id int not null,-> dimension1 varchar(500) character set utf8 collate utf8_bin not null,-> dimension2 varchar(500) character set utf8 collate utf8_bin not null,-> unique index unique_index (day, product_id, dimension1, dimension2)-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;Query OK, 0 rows affected (0.02 sec)

The examples are similar for latin1 , but I can use columns three times as long since it’s a single-byte character set.

mysql> create table if not exists latin1_test (-> day date not null,-> product_id int not null,-> dimension1 varchar(1500) not null,-> dimension2 varchar(1500) not null,-> unique index unique_index (day, product_id, dimension1, dimension2)-> ) ENGINE=InnoDB DEFAULT CHARSET=latin1;ERROR 1071 (42000): Specified key was too long; max key length is 767 bytesmysql> set global innodb_file_format = BARRACUDA;Query OK, 0 rows affected (0.00 sec)mysql> set global innodb_large_prefix = ON;Query OK, 0 rows affected (0.00 sec)mysql> create table if not exists latin1_test (-> day date not null,-> product_id int not null,-> dimension1 varchar(1500) not null,-> dimension2 varchar(1500) not null,-> unique index unique_index (day, product_id, dimension1, dimension2)-> ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;Query OK, 0 rows affected (0.02 sec)

And here’s what happens if I try to create an index longer than 3072 bytes:

mysql> create table if not exists long_index_test (-> day date not null,-> product_id int not null,-> dimension1 varchar(1500) not null,-> dimension2 varchar(1500) not null,-> dimension3 varchar(1500) not null,-> unique index unique_index (day, product_id, dimension1, dimension2, dimension3)-> ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值