關於mysql最左字首原則

2021-09-01 03:04:46 字數 1422 閱讀 1297

背景知識:

mysql中可以使用explain關鍵字來檢視sql語句的執行計畫。

最左字首原則主要使用在聯合索引中

資料庫版本mysql5.5.53

1.首先準備如下測試資料表

create table `student` (

`id` int(11) not null,

`name` varchar(255) default null,

`cid` int(11) default null,

`school` char(20) not null default '',

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

) engine=innodb default charset=utf8;

insert into student values

(1,'weixin',12,'ningbo'),

(2,'weixin',13,'ningbo'),

(3,'weixin',14,'ningbo');

2.我看了很多網上對字首原則的說明,例如abc聯合索引,只有當a或者ab或者abc為條件時才能觸發索引,這當然是毋容置疑的,但是我測試了發現ac也是會觸發聯合索引的,這是為什麼呢?

我把重點放在了key_len這一項上,key_len是指索引型別的位元組長度,那麼上面768是怎麼計算得到的呢?name列申明的是255,而且字符集是utf8,因此初步計算可以得到值為255*3=765,由於varchar有乙個特性就是超過255(應該也包括255)會額外使用兩個位元組記錄長度,因此765還需要加上2,也就是767,又因為name列為null,所以mysql需要1個位元組來標識null,因此可以計算得出最後結果為768。同理cid列可以計算得到為4+1=5,school列計算得到為20*3=60,那麼乙個聯合索引按照key_len的定義上理解的話,name_cid_inx應該是768+5+60=833,但是為什麼ac條件下觸發了聯合索引,key_len卻只是768,網上查了資料發現聯合索引可以使用部分,這也是為什麼要遵循字首原則的原因。鑑於聯合索引可以使用部分的原因,猜測ac條件之所以觸發了聯合索引是因為它與單獨使用a條件相同,為此對比只使用a條件的情況,具體如下:

根據以上表述,我們可以得出如下結論:當使用abc會完全使用聯合索引的abc三列,使用ab只會使用聯合索引中的兩列,使用a或者ac只會使用聯合索引中的a列,至於其他情況聯合索引不會被使用。

3.注意點:細心的讀者可能會發現,我們插入的測試資料name都是"weixin"但是查詢的時候卻沒有使用name="weixin"而是使用了name="weixi",原因就是當name="weixin"時命中了表中的大部分資料,mysql查詢優化器認為全表掃瞄比索引索引掃瞄效率更高而選擇了全表掃瞄,如下:

還有關於mysql的查詢優化器還有一點需要注意,sql語句中字段的順序不需要和聯合索引中定義的字段順序一致,查詢優化器會自己調整順序:

MySql最左字首原則

企業的筆試題,對資料庫這塊了解很淺,所以還是記錄一下吧。b tree 索引和 hash 索引的對比 對於 b tree 和 hash 資料結構的理解能夠有助於 不同儲存引擎下使用不同索引的查詢效能的差異,尤其是那些允許你選擇 b tree 或者 hash 索引的記憶體儲存引擎。b tree 索引的特...

MySql最左字首原則

最左字首原則 通過例項理解單列索引 多列索引以及最左字首原則 例項 現在我們想查出滿足以下條件的使用者id mysql select uid from people where lname liu and fname zhiqun and age 26 因為我們不想掃瞄整表,故考慮用索引。單列索引 ...

mysql最左字首原則

假設資料 表 t a,b,c rowid 為物理位置 rowid a b c 1 111 2 2 113 3 2214 4 1 33 5 2312 6 1 25 7 239 8 1 22 9 136 10 2 211 11 228 12 1 17 13 2315 14 1 14 15 2110 當你...