1. 程式人生 > >(ainusers原創)最左字首原則【BTree索引支援】

(ainusers原創)最左字首原則【BTree索引支援】

首先必須瞭解幾個概念:單列索引,複合索引,最左字首原則(我自己起名為:通關有序原則)
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可以最高效利用索引,保證查詢效率。