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列的大小相等,才會去看b列的大小,否則直接按照a列排序,以此類推.
- 假如直接拿 b='xxx’作為條件
- 在遍歷索引樹的時(shí)候,到頁子節(jié)點(diǎn),不能保證索引的順序,還是要去全文遍歷其他的葉子結(jié)點(diǎn)
例子
假如建立聯(lián)合索引(a,b,c)
1.全值匹配查詢時(shí)
用到了索引
where子句幾個(gè)搜索條件順序調(diào)換不影響查詢結(jié)果,因?yàn)镸ysql中有查詢優(yōu)化器,會自動優(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 .匹配范圍值
可以對最左邊的列進(jìn)行范圍查詢
select * from table_name where a > 1 and a < 3
多個(gè)列同時(shí)進(jìn)行范圍查找時(shí),只有對索引最左邊的那個(gè)列進(jìn)行范圍查找才用到B+樹索引,也就是只有a用到索引,在1<a<3的范圍內(nèi)b是無序的,不能用索引,找到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)文章
解析mysql二進(jìn)制日志處理事務(wù)與非事務(wù)性語句的區(qū)別
本篇文章是對mysql二進(jìn)制日志處理事務(wù)與非事務(wù)性語句的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06mysql觸發(fā)器實(shí)現(xiàn)oracle物化視圖示例代碼
mysql觸發(fā)器實(shí)現(xiàn)oracle物化視圖即不是基于基表的虛表,而是根據(jù)表實(shí)際存在的實(shí)表,需要的朋友可以參考下2014-02-02Windows 10系統(tǒng)下徹底刪除卸載MySQL的方法教程
mysql數(shù)據(jù)庫的重新安裝是一個(gè)麻煩的問題,很難卸除干凈,下面這篇文章主要給大家介紹了關(guān)于在Windows 10系統(tǒng)下徹底刪除卸載MySQL的方法教程,對大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-07-07asp.net 將圖片上傳到mysql數(shù)據(jù)庫的方法
圖片通過asp.net上傳到mysql數(shù)據(jù)庫的方法2009-06-06MySQL導(dǎo)入.CSV數(shù)據(jù)中文亂碼的解決方式
當(dāng)將xls或xlsx文件轉(zhuǎn)換為CSV并導(dǎo)入數(shù)據(jù)庫時(shí),可能出現(xiàn)亂碼,原因是編碼格式不是UTF-8,解決方法是使用Notepad或記事本打開CSV文件,所以本文給大家介紹了MySQL導(dǎo)入.CSV數(shù)據(jù)中文亂碼的解決方式,需要的朋友可以參考下2024-08-08使用Dify訪問mysql數(shù)據(jù)庫詳細(xì)代碼示例
這篇文章主要介紹了使用Dify訪問mysql數(shù)據(jù)庫的相關(guān)資料,并詳細(xì)講解了如何在本地搭建數(shù)據(jù)庫訪問服務(wù),使用ngrok暴露到公網(wǎng),并創(chuàng)建知識庫、數(shù)據(jù)庫訪問工作流和智能體,需要的朋友可以參考下2025-03-03如何保護(hù)MySQL中重要數(shù)據(jù)的方法
在日常的工作中,保護(hù)數(shù)據(jù)免受未授權(quán)用戶的侵犯是系統(tǒng)管理員特別關(guān)心的問題。如果你目前用的是MySQL,就可以使用一些方便的功能來保護(hù)系統(tǒng),來大大減少機(jī)密數(shù)據(jù)被未授權(quán)用戶訪問的風(fēng)險(xiǎn)2011-10-10MySQL使用distinct去掉查詢結(jié)果重復(fù)的問題
這篇文章主要介紹了MySQL使用distinct去掉查詢結(jié)果重復(fù)的問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01mysql根據(jù)拼音字母查詢(簡單易懂的字段拼音查詢)
MySQL在開發(fā)中,我們經(jīng)常需要根據(jù)字段拼音查詢數(shù)據(jù)庫中的數(shù)據(jù),它支持多種查詢方式,包括根據(jù)拼音字母查詢,使用 Collation 可以方便地進(jìn)行簡單的拼音查詢,而使用拼音索引可以大幅提高查詢性能,根據(jù)具體的需求和情況,我們可以選擇合適的方法來實(shí)現(xiàn)拼音查詢2023-10-10