MySQL Index 聯(lián)合索引探討

聯(lián)合索引也叫多列索引, 其常見的實現(xiàn)方式為連接索引(concatenated index), 它是通過將一列的值追加的一列后面形成的, 其連接的順序由創(chuàng)建索引是指定, MySQL便是使用的這種方式. 另一種方式成為多維索引(multi-dimensional index), 這種方式比較復(fù)雜, 有興趣的同學(xué)可自行搜索相關(guān)資料.

聯(lián)合索引的創(chuàng)建

  1. 隨表創(chuàng)建
CREATE TABLE `t_index_explain` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `a` varchar(20) DEFAULT NULL,
  `b` varchar(20) DEFAULT NULL,
  `c` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_a_b_c` (`a`,`b`,`c`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  1. 單獨創(chuàng)建
ALTER TABLE `t_index_explain` 
ADD INDEX `index_a_b_c`(`a`, `b`, `c`) USING BTREE;

如上兩種方式, 都是創(chuàng)建了一個a, b, c 的聯(lián)合索引, 其定義的順序是abc,故在實際索引的中的每一個值為(a, b, c)這樣一個連接組合形式, 甚至可以簡單粗暴的理解為索引列的值就是a+b+c(以字符串的方式連接在一起). 如此就把多列索引變成了我們熟悉的單列索引. 其工作原理也是一致的.

用法與注意事項

聯(lián)合索引遵循最左前綴原則, 原因是其索引值連接順序為定義的從左至右連接, 因此如下SQL是可以使用index_a_b_c索引的:

SELECT * FROM t_index_explain WHERE a  = "1" and b = "1";

如下是該SQL的解釋結(jié)果:


image.png

其中Extra 說明了我們確實使用了index, possible_keys說明了可能的index只有 index_a_b_c.

常見誤區(qū): 很多人認(rèn)為, 所謂的最左前綴原則, 需要我們編寫的SQL條件順序與定義順序一致, 其實不是的(查詢優(yōu)化器沒那么傻), 如下佐證:

SELECT * FROM t_index_explain WHERE b = "2" and a  = "1";

把a, b 條件的順序調(diào)換一下, 也會得到同樣的解釋結(jié)果. 其成立的條件應(yīng)該是條件中是否包含index定義最左邊的字段. 如下的sql與執(zhí)行結(jié)果可證明這一點.

SELECT * FROM t_index_explain WHERE c = "2" and a  = "1";

image.png

不能使用索引的情況, 在本例中只要不包含a字段的查詢, 都不能使用該聯(lián)合索引(除非索引覆蓋).

SELECT * FROM t_index_explain WHERE c = "2";
SELECT * FROM t_index_explain WHERE b = "2";
SELECT * FROM t_index_explain WHERE c = "2" and b = "1";

以上SQL解釋執(zhí)行結(jié)果:


image.png

其中Extra提示了Using Index但是possible_keys為NULL, key 中出現(xiàn)了我們創(chuàng)建的索引index_a_b_c, 其原因是發(fā)生了索引覆蓋. 如果表中的字段/數(shù)據(jù)豐富一些, 多一些可以觀察的不一樣的執(zhí)行結(jié)果, 有興趣的同學(xué)可自證.

索引與排序

眾所周知, 索引是有序的, 但是實際開發(fā)中索引字段, 與排序字段往往不是一個比如訂單表中我們需要查詢某個用戶的數(shù)據(jù), 但是按支付時間排序, SQL如下:

表:

CREATE TABLE `t_order`  (
  `id` bigint(0) NOT NULL AUTO_INCREMENT,
  `userid` bigint(0) NULL,
  `pay_time` datetime(0) NULL,
  PRIMARY KEY (`id`)
  KEY `index_userid` (`userid`) USING BETREE
);
select * from t_order where userid = 1 order by pay_time

如果創(chuàng)建的是userid的單列索引, 那么如上查詢語句解釋結(jié)果


image.png

可以看到Extra中出現(xiàn)了 Using filesort 表明該操作需要單獨進(jìn)行一次排序操作.

修改索引為聯(lián)合索引:

ALTER TABLE `micro_stories`.`t_order` 
DROP INDEX `index_userid`,
ADD INDEX `index_userid_pay_time`(`userid`, `pay_time`) USING BTREE;
image.png

如上解釋結(jié)果可以看出, 沒有filesort了. 所以索引不只可以來做查詢條件的, 也可以利用索引的有序性來做排序優(yōu)化.

總結(jié)一下

  • 聯(lián)合索引的每個索引值是以索引定義中字段的順序, 連接在一起組成的, 其索引的基本結(jié)構(gòu)仍然是B+樹
  • 聯(lián)合索引生效需要滿足條件中存在索引定義最左邊的字段(最左前綴原則)
  • 聯(lián)合所以可用于輔助排序, 提升查詢效率
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末验毡,一起剝皮案震驚了整個濱河市粗梭,隨后出現(xiàn)的幾起案子走净,更是在濱河造成了極大的恐慌,老刑警劉巖狞甚,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡朵诫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進(jìn)店門薄扁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來剪返,“玉大人,你說我怎么就攤上這事邓梅⊥衙ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵震放,是天一觀的道長宾毒。 經(jīng)常有香客問我,道長殿遂,這世上最難降的妖魔是什么诈铛? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮墨礁,結(jié)果婚禮上幢竹,老公的妹妹穿的比我還像新娘。我一直安慰自己恩静,他們只是感情好焕毫,可當(dāng)我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布蹲坷。 她就那樣靜靜地躺著,像睡著了一般邑飒。 火紅的嫁衣襯著肌膚如雪循签。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天疙咸,我揣著相機與錄音县匠,去河邊找鬼。 笑死撒轮,一個胖子當(dāng)著我的面吹牛乞旦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播题山,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼兰粉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了顶瞳?” 一聲冷哼從身側(cè)響起玖姑,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎浊仆,沒想到半個月后客峭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡抡柿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年舔琅,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洲劣。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡备蚓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出囱稽,到底是詐尸還是另有隱情郊尝,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布战惊,位于F島的核電站流昏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吞获。R本人自食惡果不足惜况凉,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望各拷。 院中可真熱鬧刁绒,春花似錦、人聲如沸烤黍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嫂丙,卻和暖如春娘赴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背奢入。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工筝闹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人腥光。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像糊秆,于是被迫代替她去往敵國和親武福。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,562評論 2 349