mysql聯(lián)合索引最左匹配原則的底層實(shí)現(xiàn)原理解讀
mysql聯(lián)合索引最左匹配原則的底層實(shí)現(xiàn)原理
要看懂,需要熟悉mysql b+ tree的數(shù)據(jù)結(jié)構(gòu)
b+tree的葉節(jié)點(diǎn)和葉子節(jié)點(diǎn)的排序特性是按照,從小到大,從左到右的這么一個(gè)規(guī)則,int直接比大小,uuid比較ASCII碼,
- 聯(lián)合索引的排序規(guī)則
- 拿a_b_c_idx為例,優(yōu)先比較a列的大小,如果a列的大小相等,才會(huì)去看b列的大小,否則直接按照a列排序,以此類推.
- 假如直接拿 b='xxx’作為條件
- 在遍歷索引樹的時(shí)候,到頁(yè)子節(jié)點(diǎn),不能保證索引的順序,還是要去全文遍歷其他的葉子結(jié)點(diǎn)
例子
假如建立聯(lián)合索引(a,b,c)
1.全值匹配查詢時(shí)
用到了索引
where子句幾個(gè)搜索條件順序調(diào)換不影響查詢結(jié)果,因?yàn)镸ysql中有查詢優(yōu)化器,會(huì)自動(dòng)優(yōu)化查詢順序
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'
2.匹配左邊的列時(shí)
都從最左邊開始連續(xù)匹配,用到了索引
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'
如果不連續(xù)時(shí),只用到了a列的索引,b列和c列都沒有用到
select * from table_name where a = '1' and c = '3'
3.匹配列前綴
如果列是字符型的話它的比較規(guī)則是先比較字符串的第一個(gè)字符,第一個(gè)字符小的那個(gè)字符串就比較小,如果兩個(gè)字符串第一個(gè)字符相通,那就再比較第二個(gè)字符,第二個(gè)字符比較小的那個(gè)字符串就比較小,依次類推,比較字符串。
如果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 .匹配范圍值
可以對(duì)最左邊的列進(jìn)行范圍查詢
select * from table_name where a > 1 and a < 3
多個(gè)列同時(shí)進(jìn)行范圍查找時(shí),只有對(duì)索引最左邊的那個(gè)列進(jìn)行范圍查找才用到B+樹索引,也就是只有a用到索引,在1<a<3的范圍內(nèi)b是無(wú)序的,不能用索引,找到1<a<3的記錄后,只能根據(jù)條件 b > 1繼續(xù)逐條過濾
select * from table_name where a > 1 and a < 3 and b > 1;
5.精確匹配某一列并范圍匹配另外一列
如果左邊的列是精確查找的,右邊的列可以進(jìn)行范圍查找
select * from table_name where a = 1 and b > 3;
a=1的情況下b是有序的,進(jìn)行范圍查找走的是聯(lián)合索引
6.排序
order by的子句后面的順序也必須按照索引列的順序給出,比如
select * from table_name order by a,b,c limit 10;
這種顛倒順序的沒有用到索引
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;
聯(lián)合索引左邊列為常量,后邊的列排序可以用到索引
select * from table_name where a =1 order by b,c limit 10;
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決Linux安裝mysql 在/etc下沒有my.cnf的問題
這篇文章主要介紹了解決Linux安裝mysql 在/etc下沒有my.cnf的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2021-01-01
InnoDB中不同SQL語(yǔ)句設(shè)置鎖的情況詳解
這篇文章主要介紹了InnoDB中不同SQL語(yǔ)句設(shè)置鎖的情況詳解,在Mysql中,鎖定讀、更新、刪除操作通常會(huì)對(duì)SQL語(yǔ)句處理過程中掃描到的每條索引記錄設(shè)置記錄鎖,需要的朋友可以參考下2024-01-01
簡(jiǎn)單了解mysql InnoDB MyISAM相關(guān)區(qū)別
這篇文章主要介紹了簡(jiǎn)單了解mysql InnoDB MyISAM相關(guān)區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
MySQL使用正則表達(dá)式來(lái)更好地控制數(shù)據(jù)過濾
MySQL中的正則表達(dá)式是一種強(qiáng)大的數(shù)據(jù)過濾工具,它允許用戶以靈活的方式匹配和搜索文本數(shù)據(jù),這篇文章主要給大家介紹了關(guān)于MySQL使用正則表達(dá)式來(lái)更好地控制數(shù)據(jù)過濾的相關(guān)資料,需要的朋友可以參考下2024-08-08
mysql使用xtrbackup+relaylog增量恢復(fù)注意事項(xiàng)
這篇文章主要介紹了mysql使用xtrbackup+relaylog增量恢復(fù),本次實(shí)驗(yàn)mysql5.7.19.使用了GTID,row格式的binlog,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05

