不同於oracle,在mysql的Innodb存儲引擎中,對索引的總長度有限制。在mysql 5.7中(https://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html),默認為3072。
If innodb_large_prefix
is enabled (the default), the index key prefix limit is 3072 bytes for InnoDB
tables that use DYNAMIC
orCOMPRESSED
row format. If innodb_large_prefix
is disabled, the index key prefix limit is 767 bytes for tables of any row format.
innodb_large_prefix
is deprecated and will be removed in a future release. innodb_large_prefix
was introduced in MySQL 5.5 to disable large index key prefixes for compatibility with earlier versions of InnoDB
that do not support large index key prefixes.
The index key prefix length limit is 767 bytes for InnoDB
tables that use the REDUNDANT
or COMPACT
row format. For example, you might hit this limit with a column prefix index of more than 255 characters on a TEXT
or VARCHAR
column, assuming a utf8mb3
character set and the maximum of 3 bytes for each character.
Attempting to use an index key prefix length that exceeds the limit returns an error. To avoid such errors in replication configurations, avoid enabling innodb_large_prefix
on the master if it cannot also be enabled on slaves.
The limits that apply to index key prefixes also apply to full-column index keys.
所以在GBK編碼中,最大可以到1536個字符,utf8/utf8mb3,1024個字符,utf8mb4為768個字符。這一限制為天然限制(mariadb因為采用Innodb引擎,該限制同樣存在),無法繞開。
drop table big_index_test;
create table big_index_test(id int,content varchar(1000)) ROW_FORMAT=DYNAMIC CHARACTER set = utf8mb4 ;
create index idx_big_index on big_index_test(content);
[SQL]create index idx_big_index on big_index_test(content);
[Err] 1071 - Specified key was too long; max key length is 3072 bytes
相對於oracle來說,如果定義存在這種情況,即使記錄沒有或很少,仍然無法利用索引覆蓋查詢實現一些寬表的優化。
因此,對於mysql而言,對於一些定義很長的detail,最好的方式是垂直拆表,也就是將id和detail字段存儲在單獨的表中,然后業務代碼中二次select的方式優化。如果detail字段是json類型的話,可以直接存儲為json類型或存儲在NoSQL中如mongodb。
注:當年5.6的時候,幫一個產品優化過mysql,mysql在大字段的處理上性能非常低下。