(ainusers原創)最左字首原則【BTree索引支援】
阿新 • • 發佈:2018-11-09
首先必須瞭解幾個概念:單列索引,複合索引,最左字首原則(我自己起名為:通關有序原則) 1. 索引建立的原則 用於索引的最好的備選資料列是那些出現在WHERE子句、join子句、ORDER BY或GROUP BY子句中的列。 僅僅出現在SELECT關鍵字後面的輸出資料列列表中的資料列不是很好的備選列 2.單列索引 舉個栗子 索引index(lname) 走索引情況 SELECT `uid` FROM people WHERE lname`='Liu' 3.複合索引 舉個栗子 索引index(a,b,c) 不會走索引情況 select * from table where c = '1' select * from table where b =‘1’ and c ='2' 會走索引情況 select * from table where a = '1' select * from table where a = '1' and b = ‘2’ select * from table where a = '1' and b = ‘2’ and c='3' 原因:索引index(a,b,c),只會走a、a,b、a,b,c 三種類型的查詢(ac同樣也會走,但是隻使用a索引,不會使用c索引) 注:select * from table where a = '1' and b > ‘2’ and c='3' 這種情況只會走a,b為什麼?因為索引是有序的,走索引會先根據a排序,再根據b排序(由於b是範圍查詢並未有序,故c無法使用索引(即無序狀態)) 個人理解小結: 1.如上覆合索引猶如通關,想過第二關必須通過第一關,第一關的狀態必須是win贏而不是輸,也就是a必須走索引,狀態是有序並不是無序。->這裡體現了我上面所說的最左字首原則中的最左(即通關有序原則) 2.我們建立了index複合索引,相當於建立了(a)單列索引,(a,b)組合索引以及(a,b,c)組合索引。這裡應該體現了字首了吧(趕腳不太明顯哈) 下面有兩個經典的栗子,我在這裡引用一下 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 執行1: EXPLAIN SELECT * FROM student WHERE name='小紅'; //type=ref 執行2: EXPLAIN SELECT * FROM student WHERE cid=1; //type=index 執行3: EXPLAIN SELECT * FROM student WHERE cid=1 AND name='小紅'; //type=ref 1.上面竟然可以使用索引? 是的 解釋: index:mysql會掃描索引列表,只要是索引或者複合索引的一部分,才會使用index ref:mysql會根據特定的演算法快速查詢到某個符合條件的索引,而不是會對索引中每一個數據都進行一 一的掃描判斷,也就是所謂你平常理解的使用索引查詢會更快的取出資料。 分析執行3 索引是index(name,cid) 2.查詢的語句是cid=1 AND name='小紅'; 我是先查詢cid,再查詢name的,不是先從最左面查的呀? 首先我可以確定的是兩種情況查詢效率是一樣的(cid=1 AND name='小紅';/name='小紅' AND cid=1;) 主要是由於mysql優化器的作用:mysql優化器會調整sql的順序,來保證sql可以最高效利用索引,保證查詢效率。