MySQL的復合索引可以創(chuàng)建多個,每個復合索引可以包含一列或多列。復合索引使用的基本原則是左側(cè)對齊原則。例如,復合索引包含A,B,C字段,實際相當于創(chuàng)建了5個索引,即:

創(chuàng)新互聯(lián)長期為上千家客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為清流企業(yè)提供專業(yè)的網(wǎng)站建設、成都網(wǎng)站建設,清流網(wǎng)站改版等技術(shù)服務。擁有十年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
那么問題來了,如果我們創(chuàng)建兩個復合索引,復合索引1:包含A,B,C列和復合索引2:包含B,C列,MySQL如何執(zhí)行呢?
按照正常的邏輯,和復合索引的原則,應該能命中的索引是A_B_C_index,讓我們拭目以待吧!
結(jié)果:和上次測試的不一致,這次雖然包含ABC三個列,但命中的索引是B_C_index
重要結(jié)論:當命中兩個或者多個不同的復合索引時,按照創(chuàng)建順序不同,MySQL會有不同策略來選取其中的一個復合索引。
聯(lián)合索引是由多個字段組成的索引。CREATE
[UNIQUE|FULLTEXT|SPATIAL]
INDEX
index_name[USING
index_type]ON
tbl_name
(index_col_name,...)index_col_name:col_name[(length)]
[ASC
|
DESC]如果你經(jīng)常要用到多個字段的多條件查詢,可以考慮建立聯(lián)合索引,一般是除第一個字段外的其它字段不經(jīng)常用于條件篩選情況,比如說a,b
兩個字段,如果你經(jīng)常用a條件或者a+b條件去查詢,而很少單獨用b條件查詢,那么可以建立a,b的聯(lián)合索引。
你有索引index1(a,b,c),這是是聯(lián)合索引,也叫復合索引、多列索引;
你有索引index2(a),index3(b),index4(c),然后你的sql中有and、or或union之類的條件對三個索引分別進行條件掃描,然后將各自的結(jié)果進行合并,這叫索引合并,這時你用explain查看執(zhí)行計劃會看到有“index merge”字樣。
至于兩者有沒有關(guān)系,這怎么講呢,一般來說,聯(lián)合索引(復合索引)的效率要比索引合并要高,在能使用聯(lián)合索引時盡量使用聯(lián)合索引,當然這要根據(jù)具體情況,sql中寸在“or”這樣的連接詞時,那就可能必須要使用索引合并了。
索引合并是mysql底層為我們提供的智能算法。了解索引合并的算法,有助于我們更好的創(chuàng)建索引。
索引合并是通過多個range類型的掃描并且合并它們的結(jié)果集來檢索行的。僅合并來自單個表的索引掃描,而不是跨多個表的索引掃描。合并會產(chǎn)生底層掃描的三種形式:unions(合并)、intersections(交集)、unions-of-intersections(先取交集再合并)。
以下四個例子會產(chǎn)生索引合并:
索引合并有以下已知的局限性:
1、如果查詢語句包含一個帶有嚴重AND/OR嵌套的復雜的WHERE子句而MySQL沒有選擇最佳計劃,那么可以嘗試使用以下的標志符轉(zhuǎn)換:
(x AND y) OR z = (x OR z) AND (y OR z)
(x OR y) AND z = (x AND z) OR (y AND z)
2、索引合并不適用于全文索引。
在 EXPLAIN 語句輸出的信息中,索引合并在type列中表現(xiàn)為“index_merge”,在這種情況下,key列包含使用的索引列表。
索引合并訪問方法有幾種算法,表現(xiàn)在 EXPLAIN 語句輸出的Extra字段中:
下面將更詳細地描述這些算法。優(yōu)化器根據(jù)各種可用選項的成本估計,在不同的索引合并算法和其他訪問方法之間進行選擇。
Index Merge Intersection算法
Index Merge Intersection算法對所有使用的索引執(zhí)行同步掃描,并生成從合并的索引掃描接收到的行序列的交集。
這種算法適用于當WHERE子句被轉(zhuǎn)換成多個使用AND連接的不同索引key上的范圍條件,且條件是以下兩種之一:
一、這種形式的N部分表達式,索引正好包括N個字段(所有索引字段都被覆蓋),N=1,N如果大于1就是復合索引:
二、InnoDB表主鍵上的任何范圍條件。
例子:
Index Merge Union算法
該算法類似于Index Merge Intersection算法,適用于當WHERE子句被轉(zhuǎn)換成多個使用OR連接的不同索引key上的范圍條件,且條件是以下三種之一:
一、這種形式的N部分表達式,索引正好包括N個字段(所有索引字段都被覆蓋),N=1,N如果大于1就是復合索引:
二、InnoDB表主鍵上的任何范圍條件。
三、符合Index Merge Intersection算法的條件。
例子:
Index Merge Sort-Union算法
該算法適用于當WHERE子句被轉(zhuǎn)換成多個使用OR連接的不同索引key上的范圍條件,但是不符合 Index Merge Union算法的。Index Merge Sort-Union和Index Merge Union算法的區(qū)別在于,Index Merge Sort-Union必須首先獲取所有行的行id并在返回任何行之前對它們進行排序。
例子:
有好的建議,請在下方輸入你的評論。
歡迎訪問個人博客
在一個市民信息表上,是否有必要將身份證號
和名字建立聯(lián)合索引?
假設這個市民表的定義是這樣的:
CREATE TABLE `tuser` (
`id` int(11) NOT NULL,
`id_card` varchar(32) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`ismale` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `id_card` (`id_card`),
KEY `name_age` (`name`,`age`)
) ENGINE=InnoDB
我們知道,身份證號是市民的唯一標識。也就是說,如果有根據(jù)身份證號查詢市民信息的需求,
我們只要在身份證號字段上建立索引就夠了。而再建立一個(身份證號、姓名)的聯(lián)合索引,是
不是浪費空間?
如果現(xiàn)在有一個高頻請求,要根據(jù)市民的身份證號查詢他的姓名,這個聯(lián)合索引就有意義了。它
可以在這個高頻請求上用到覆蓋索引,不再需要回表查整行記錄,減少語句的執(zhí)行時間。
當然,索引字段的維護總是有代價的。因此,在建立冗余索引來支持覆蓋索引時就需要權(quán)衡考慮
了。這正是業(yè)務 DBA,或者稱為業(yè)務數(shù)據(jù)架構(gòu)師的工作。
最左前綴原則
看到這里你一定有一個疑問,如果為每一種查詢都設計一個索引,索引是不是太多了。如果我現(xiàn)
在要按照市民的身份證號去查他的家庭地址呢?雖然這個查詢需求在業(yè)務中出現(xiàn)的概率不高,但
總不能讓它走全表掃描吧?反過來說,單獨為一個不頻繁的請求創(chuàng)建一個(身份證號,地址)的
索引又感覺有點浪費。應該怎么做呢?
這里,我先和你說結(jié)論吧。B+ 樹這種索引結(jié)構(gòu),可以利用索引的“最左前綴”,來定位記錄。
為了直觀地說明這個概念,我們用(name,age)這個聯(lián)合索引來分析。
? ? ? ? ? ? ? ? ?圖 2 (name,age)索引示意圖
可以看到,索引項是按照索引定義里面出現(xiàn)的字段順序排序的。
當你的邏輯需求是查到所有名字是“張三”的人時,可以快速定位到 ID4,然后向后遍歷得到所有
需要的結(jié)果。
如果你要查的是所有名字第一個字是“張”的人,你的 SQL 語句的條件是"where name like ‘張
%’"。這時,你也能夠用上這個索引,查找到第一個符合條件的記錄是 ID3,然后向后遍歷,直
到不滿足條件為止。
可以看到,不只是索引的全部定義,只要滿足最左前綴,就可以利用索引來加速檢索。這個最左
前綴可以是聯(lián)合索引的最左 N 個字段,也可以是字符串索引的最左 M 個字符。
基于上面對最左前綴索引的說明,我們來討論一個問題:在建立聯(lián)合索引的時候,如何安排索引
內(nèi)的字段順序。
這里我們的評估標準是,索引的復用能力。因為可以支持最左前綴,所以當已經(jīng)有了 (a,b) 這個
聯(lián)合索引后,一般就不需要單獨在 a 上建立索引了。因此,第一原則是,如果通過調(diào)整順序,可
以少維護一個索引,那么這個順序往往就是需要優(yōu)先考慮采用的。
所以現(xiàn)在你知道了,這段開頭的問題里,我們要為高頻請求創(chuàng)建 (身份證號,姓名)這個聯(lián)合索
引,并用這個索引支持“根據(jù)身份證號查詢地址”的需求。
那么,如果既有聯(lián)合查詢,又有基于 a、b 各自的查詢呢?查詢條件里面只有 b 的語句,是無法
使用 (a,b) 這個聯(lián)合索引的,這時候你不得不維護另外一個索引,也就是說你需要同時維護
(a,b)、(b) 這兩個索引。
這時候,我們要考慮的原則就是空間了。比如上面這個市民表的情況,name 字段是比 age 字段
大的 ,那我就建議你創(chuàng)建一個(name,age) 的聯(lián)合索引和一個 (age) 的單字段索引。
網(wǎng)站題目:mysql怎么合并索引 索引合并怎么回事
轉(zhuǎn)載來于:http://chinadenli.net/article8/doohdop.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設計公司、網(wǎng)頁設計公司、App開發(fā)、企業(yè)建站、軟件開發(fā)、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)