從innodb的索引結(jié)構(gòu)分析,為什么索引的key不能太長(zhǎng)

一闽巩、myisam存儲(chǔ)引擎

1 . 測(cè)試的表結(jié)構(gòu)信息

mysql> show create table tb2
Table: tb2
Create Table: CREATE TABLE `tb2` (
`a1` varchar(255) DEFAULT NULL,
`b1` varchar(255) DEFAULT NULL,
`c1` varchar(255) DEFAULT NULL,
`d1` varchar(1000) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
  1. 測(cè)試加索引

(1)添加單列索引钧舌,能夠添加成功(報(bào)出warning),但實(shí)際添加的是前綴索引涎跨。

mysql> alter table tb2 add index idx1 (d1);
Query OK, 0 rows affected, 2 warnings (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> show warnings;
+---------+------+----------------------------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------------------------+
| Warning | 1071 | Specified key was too long; max key length is 1000 bytes |
| Warning | 1071 | Specified key was too long; max key length is 1000 bytes |
+---------+------+----------------------------------------------------------+
2 rows in set (0.00 sec)

表結(jié)構(gòu)信息:

mysql> show create table tb2
Table: tb2
Create Table: CREATE TABLE `tb2` (
`a1` varchar(255) DEFAULT NULL,
`b1` varchar(255) DEFAULT NULL,
`c1` varchar(255) DEFAULT NULL,
`d1` varchar(1000) DEFAULT NULL,
KEY `idx1` (`d1`(333))
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

(2)添加組合索引洼冻,會(huì)執(zhí)行失敗。

mysql> alter table tb2 add index idx1 (a1,b1);
ERROR 1071 (42000): Specified key was too long; max key length is 1000 bytes
  1. 分析

myisam存儲(chǔ)引擎在創(chuàng)建索引的時(shí)候隅很,索引鍵長(zhǎng)度是有一個(gè)較為嚴(yán)格的長(zhǎng)度限制的撞牢,所有索引鍵最大長(zhǎng)度總和不能超過(guò)1000,而且不是實(shí)際數(shù)據(jù)長(zhǎng)度的總和叔营,而是索引鍵字段定義長(zhǎng)度的總和屋彪。

主要字符集的計(jì)算方式:
latin1 = 1 byte = 1 character
uft8 = 3 byte = 1 character
gbk = 2 byte = 1 character

二、innodb存儲(chǔ)引擎

  1. 表結(jié)構(gòu)信息:
mysql> create table tb1 (a1 varchar(255), b1 varchar(255), c1 varchar(255), d1 varchar(1000));
Query OK, 0 rows affected (0.01 sec)

2. 添加組合索引绒尊,報(bào)出waring畜挥,實(shí)際在某個(gè)單列上添加的是前綴索引

mysql> alter table tb1 add index idx1(a1,b1,c1,d1);

*Query OK, 0 rows affected, 2 warnings (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0*

mysql> show warnings;
+---------+------+---------------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------------+
| Warning | 1071 | Specified key was too long; max key length is 767 bytes |
| Warning | 1071 | Specified key was too long; max key length is 767 bytes |
+---------+------+---------------------------------------------------------+
2 rows in set (0.00 sec)

3. 添加單列索引,報(bào)出waring婴谱,實(shí)際添加的是前綴索引

mysql> alter table tb1 add index idx2(d1);
Query OK, 0 rows affected, 2 warnings (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> show warnings;
+---------+------+---------------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------------+
| Warning | 1071 | Specified key was too long; max key length is 767 bytes |
| Warning | 1071 | Specified key was too long; max key length is 767 bytes |
+---------+------+---------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> show create table tb1
Table: tb1
Create Table: CREATE TABLE `tb1` (
`a1` varchar(255) DEFAULT NULL,
`b1` varchar(255) DEFAULT NULL,
`c1` varchar(255) DEFAULT NULL,
`d1` varchar(1000) DEFAULT NULL,
KEY `idx1` (`a1`,`b1`,`c1`,`d1`(255)),
KEY `idx2` (`d1`(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
  1. 分析:

默認(rèn)情況下蟹但,InnoDB 引擎單一字段索引的長(zhǎng)度最大為 767 字節(jié),同樣的谭羔,前綴索引也有同樣的限制华糖。當(dāng)使用 UTF-8 字符集,每一個(gè)字符使用 3 字節(jié)來(lái)存儲(chǔ)瘟裸,在 TEXT 或者 VARCHAR 類型的字段上建立一個(gè)超過(guò) 255 字符數(shù)的前綴索引時(shí)就會(huì)遇到問(wèn)題客叉。可以啟用服務(wù)器選項(xiàng) innodb_large_prefix 使得這個(gè)限制增加到 3072 字節(jié)景描,而且表的 row_format 需要使用 compressed 或者 dynamic十办。

三、使用前綴索引帶來(lái)的風(fēng)險(xiǎn):

INNODB的索引會(huì)限制單獨(dú)Key的最大長(zhǎng)度為767字節(jié)超棺,超過(guò)這個(gè)長(zhǎng)度必須建立小于等于767字節(jié)的前綴索引。

此外呵燕,BLOB和TEXT類型的列只能創(chuàng)建前綴索引棠绘。

前綴索引能提高索引建立速度和檢索速度,但是下面情況是無(wú)法使用前綴索引的:

  • 索引覆蓋掃描
  • 通過(guò)索引的排序(order by, group by)

還是在上面的測(cè)試表上:

mysql> explain select * from tb1 order by d1;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | tb1 | ALL | NULL | NULL | NULL | NULL | 5 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

mysql> explain select * from tb1 group by d1;
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
| 1 | SIMPLE | tb1 | ALL | NULL | NULL | NULL | NULL | 5 | Using temporary; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
1 row in set (0.00 sec)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末再扭,一起剝皮案震驚了整個(gè)濱河市氧苍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌泛范,老刑警劉巖让虐,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異罢荡,居然都是意外死亡赡突,警方通過(guò)查閱死者的電腦和手機(jī)对扶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)惭缰,“玉大人浪南,你說(shuō)我怎么就攤上這事∈埽” “怎么了络凿?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)昂羡。 經(jīng)常有香客問(wèn)我絮记,道長(zhǎng),這世上最難降的妖魔是什么虐先? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任到千,我火速辦了婚禮,結(jié)果婚禮上赴穗,老公的妹妹穿的比我還像新娘憔四。我一直安慰自己,他們只是感情好般眉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布了赵。 她就那樣靜靜地躺著,像睡著了一般甸赃。 火紅的嫁衣襯著肌膚如雪柿汛。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,115評(píng)論 1 296
  • 那天埠对,我揣著相機(jī)與錄音络断,去河邊找鬼。 笑死项玛,一個(gè)胖子當(dāng)著我的面吹牛貌笨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播襟沮,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼锥惋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了开伏?” 一聲冷哼從身側(cè)響起膀跌,我...
    開(kāi)封第一講書(shū)人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎固灵,沒(méi)想到半個(gè)月后捅伤,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡巫玻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年丛忆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了祠汇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蘸际,死狀恐怖座哩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情粮彤,我是刑警寧澤根穷,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站导坟,受9級(jí)特大地震影響屿良,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惫周,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一尘惧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧递递,春花似錦喷橙、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至菠秒,卻和暖如春疙剑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背践叠。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工言缤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人禁灼。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓管挟,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親匾二。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哮独,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容