Mysql最左匹配原則

2021-10-08 20:21:10 字數 3875 閱讀 5987

看了好多部落格,講講自己的理解:索引的底層是一顆b+樹,那麼聯合索引當然還是一顆b+樹,只不過聯合索引的健值數量不是乙個,而是多個。構建一顆b+樹只能根據乙個值來構建,因此資料庫依據聯合索引最左的字段來構建b+樹。

例子:假如建立乙個(a,b)的聯合索引,那麼它的索引樹是這樣的

可以看到a的值是有順序的,1,1,2,2,3,3,而b的值是沒有順序的1,2,1,4,1,2。所以b = 2這種查詢條件沒有辦法利用索引,因為聯合索引首先是按a排序的,b是無序的。

同時我們還可以發現在a值相等的情況下,b值又是按順序排列的,但是這種順序是相對的。所以最左匹配原則遇上範圍查詢就會停止,剩下的字段都無法使用索引。例如a = 1 and b = 2 a,b欄位都可以使用索引,因為在a值確定的情況下b是相對有序的,而a>1and b=2,a欄位可以匹配上索引,但b值不可以,因為a的值是乙個範圍,在這個範圍中b是無序的。

最左匹配原則:最左優先,以最左邊的為起點任何連續的索引都能匹配上。同時遇到範圍查詢(>、

假如建立聯合索引(a,b,c)

1 全值匹配查詢時

select * 

from table_name

where a =

'1'and b =

'2'and c =

'3'select *

from table_name

where b =

'2'and a =

'1'and c =

'3'select *

from table_name

where c =

'3'and b =

'2'and a =

'1'......

用到了索引

where子句幾個搜尋條件順序調換不影響查詢結果,因為mysql中有查詢優化器,會自動優化查詢順序 

2 匹配左邊的列時

select * 

from table_name

where a =

'1'select *

from table_name

where a =

'1'and b =

'2'select *

from table_name

where a =

'1'and b =

'2'and c =

'3'

都從最左邊開始連續匹配,用到了索引

select * 

from table_name

where b =

'2'select *

from table_name

where c =

'3'select *

from table_name

where b =

'1'and c =

'3'

這些沒有從最左邊開始,最後查詢沒有用到索引,用的是全表掃瞄 

select * from table_name where a = '1'

and c = '3'

如果不連續時,只用到了a列的索引,b列和c列都沒有用到 

3 匹配列字首

如果列是字元型的話它的比較規則是先比較字串的第乙個字元,第乙個字元小的哪個字串就比較小,如果兩個字串第乙個字元相通,那就再比較第二個字元,第二個字元比較小的那個字串就比較小,依次類推,比較字串。

如果a是字元型別,那麼字首匹配用的是索引,字尾和中綴只能全表掃瞄了

select * 

from table_name

where a

like

'as%'; //字首都是排好序的,走索引查詢

select *

from table_name

where  a

like

'%as'//全表查詢

select *

from table_name

where  a

like

'%as%'//全表查詢

4 匹配範圍值

select * from table_name where  a > 1

and a < 3

可以對最左邊的列進行範圍查詢

select * from table_name where  a > 1

and a < 3

and b > 1;

多個列同時進行範圍查詢時,只有對索引最左邊的那個列進行範圍查詢才用到b+樹索引,也就是只有a用到索引,在11繼續逐條過濾

5 精確匹配某一列並範圍匹配另外一列

如果左邊的列是精確查詢的,右邊的列可以進行範圍查詢

select * from table_name where  a = 1

and b > 3;

a=1的情況下b是有序的,進行範圍查詢走的是聯合索引

6 排序

一般情況下,我們只能把記錄載入到記憶體中,再用一些排序演算法,比如快速排序,歸併排序等在記憶體中對這些記錄進行排序,有時候查詢的結果集太大不能在記憶體中進行排序的話,還可能暫時借助磁碟空間存放中間結果,排序操作完成後再把排好序的結果返回客戶端。mysql中把這種再記憶體中或磁碟上進行排序的方式統稱為檔案排序。檔案排序非常慢,但如果order子句用到了索引列,就有可能省去檔案排序的步驟

select * from table_name order

by a,b,c limit

10;

因為b+樹索引本身就是按照上述規則排序的,所以可以直接從索引中提取資料,然後進行回表操作取出該索引中不包含的列就好了

order by的子句後面的順序也必須按照索引列的順序給出,比如

select * from table_name order

by b,c,a limit

10;

這種顛倒順序的沒有用到索引

select * 

from table_name

order

by a

limit

10;

select *

from table_name

order

by a,b

limit

10;

這種用到部分索引

select * from table_name where a =1

order

by b,c limit

10;

聯合索引左邊列為常量,後邊的列排序可以用到索引

看了好多部落格,講講自己的理解:索引的底層是一顆b+樹,那麼聯合索引當然還是一顆b+樹,只不過聯合索引的健值數量不是乙個,而是多個。構建一顆b+樹只能根據乙個值來構建,因此資料庫依據聯合索引最左的字段來構建b+樹。

例子:假如建立乙個(a,b)的聯合索引,那麼它的索引樹是這樣的

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

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

最左匹配原則

寫在前面 我在上大學的時候就聽說過資料庫的最左匹配原則,當時是通過各大部落格論壇了解的,但是這些部落格的侷限性在於它們對最左匹配原則的描述就像一些數學定義一樣,往往都是列出123點,滿足這123點就能匹配上索引,否則就不能。但是我覺得程式設計不是死記硬背,這個所謂最左匹配原則肯定是有他背後的原理的。...

MySQL索引 最左匹配原則

表結構,有三個字段,分別是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 k...