MySQL索引 最左匹配原則

2021-08-18 18:09:04 字數 2603 閱讀 1494

表結構,有三個字段,分別是id,name,cid

create

table

`student` (

`id`

int(11) not

null auto_increment,

`name`

varchar(255) default

null,

`cid`

int(11) default

null,

primary

key (`id`),

key`name_cid_inx` (`name`,`cid`),

key`name_inx` (`name`)

) engine=innodb auto_increment=8

default charset=utf8

索引方面:id是主鍵,(name,cid)是乙個多列索引。

下面是兩個查詢:

explain select * from student where   cid=1;

explain select * from student where cid=1

and name='小紅';

疑問的是:sql查詢用到索引的條件是必須要遵守最左字首原則,為什麼上面兩個查詢還能用到索引?

講上面問題之前,我先補充一些知識:

上述你的兩個查詢的explain結果中顯示用到索引的情況型別是不一樣的。,可觀察explain結果中的type欄位。你的查詢中分別是:

1. type: index

2. type: ref

解釋:

index:這種型別表示是mysql會對整個該索引進行掃瞄。要想用到這種型別的索引,對這個索引並無特別要求,只要是索引,或者某個復合索引的一部分,mysql都可能會採用index型別的方式掃瞄。但是呢,缺點是效率不高,mysql會從索引中的第乙個資料乙個個的查詢到最後乙個資料,直到找到符合判斷條件的某個索引。

所以:對於第一條語句:

explain select * from student where   cid=1;
判斷條件是cid=1,而cid是(name,cid)復合索引的一部分,沒有問題,可以進行index型別的索引掃瞄方式。explain顯示結果使用到了索引,是index型別的方式。

ref:這種型別表示mysql會根據特定的演算法快速查詢到某個符合條件的索引,而不是會對索引中每乙個資料都進行一 一的掃瞄判斷,也就是所謂你平常理解的使用索引查詢會更快的取出資料。而要想實現這種查詢,索引卻是有要求的,要實現這種能快速查詢的演算法,索引就要滿足特定的資料結構。簡單說,也就是索引欄位的資料必須是有序的,才能實現這種型別的查詢,才能利用到索引。

有些了解的人可能會問,索引不都是乙個有序排列的資料結構麼。不過答案說的還不夠完善,那只是針對單個索引,而復合索引的情況有些同學可能就不太了解了。

下面就說下復合索引:

以該錶的(name,cid)復合索引為例,它內部結構簡單說就是下面這樣排列的:

mysql建立復合索引的規則是首先會對復合索引的最左邊的,也就是第乙個name欄位的資料進行排序,在第乙個欄位的排序基礎上,然後再對後面第二個的cid欄位進行排序。其實就相當於實現了類似 order by name cid這樣一種排序規則。

所以:第乙個name欄位是絕對有序的,而第二字段就是無序的了。所以通常情況下,直接使用第二個cid欄位進行條件判斷是用不到索引的,當然,可能會出現上面的使用index型別的索引。這就是所謂的mysql為什麼要強調最左字首原則的原因。

那麼什麼時候才能用到呢?

當然是cid欄位的索引資料也是有序的情況下才能使用咯,什麼時候才是有序的呢?觀察可知,當然是在name欄位是等值匹配的情況下,cid才是有序的。發現沒有,觀察兩個name名字為 c 的cid欄位是不是有序的呢。從上往下分別是4 5。

這也就是mysql索引規則中要求復合索引要想使用第二個索引,必須先使用第乙個索引的原因。(而且第乙個索引必須是等值匹配)。

所以對於你的這條sql查詢:

explain select * from student where   cid=1

and name='小紅';

沒有錯,而且復合索引中的兩個索引欄位都能很好的利用到了!因為語句中最左面的name欄位進行了等值匹配,所以cid是有序的,也可以利用到索引了。

你可能會問:我建的索引是(name,cid)。而我查詢的語句是cid=1 and name=』小紅』; 我是先查詢cid,再查詢name的,不是先從最左面查的呀?

好吧,我再解釋一下這個問題:首先可以肯定的是把條件判斷反過來變成這樣 name=』小紅』 and cid=1; 最後所查詢的結果是一樣的。

那麼問題產生了?既然結果是一樣的,到底以何種順序的查詢方式最好呢?

所以,而此時那就是我們的mysql查詢優化器該登場了,mysql查詢優化器會判斷糾正這條sql語句該以什麼樣的順序執行效率最高,最後才生成真正的執行計畫。所以,當然是我們能盡量的利用到索引時的查詢順序效率最高咯,所以mysql查詢優化器會最終以這種順序進行查詢執行。

mysql取締最左匹配原則 最左匹配原則

一 這條sql語句select from dept where age 12 and name like a 雖然age條件在前,name在後,看似不滿足最左側原則,但這條語句在執行的過程中mysql優化器會將該條語句優化為select from dept where name like a and...

Mysql 聯合索引最左匹配原則

二 測試現象 drop table if exists test table create table test table id int 11 not null auto increment comment 編號 namee varchar 255 default null comment 姓名 ...

Mysql最左匹配原則

看了好多部落格,講講自己的理解 索引的底層是一顆b 樹,那麼聯合索引當然還是一顆b 樹,只不過聯合索引的健值數量不是乙個,而是多個。構建一顆b 樹只能根據乙個值來構建,因此資料庫依據聯合索引最左的字段來構建b 樹。例子 假如建立乙個 a,b 的聯合索引,那麼它的索引樹是這樣的 可以看到a的值是有順序...