mysql 聯合索引匹配原則


讀mysql文檔有感

  看了mysql關於索引的文檔,網上有一些錯誤的博客文檔,這里我自己記一下。

幾個重要的概念

  1.對於mysql來說,一條sql中,一個表無論其蘊含的索引有多少,但是有且只用一條。
  2.對於多列索引來說(a,b,c)其相當於3個索引(a),(a,b),(a,b,c)3個索引,又由於mysql的索引優化器,其where條件后的語句是可以亂序的,比如(b,c,a)也是可以用到索引。如果條件中a,c出現的多,為了更好的利用索引故最好將其修改為(a.c,b)。

ICP概念

  看了一篇大神的博客,上面說了通用索引匹配原則,這里也順便說下。
  1.Index range 先確認索引的起止范圍。
  2.Index Filter 索引過濾。
  3.Table Filter 表過濾。
  傳說中mysql5.6后提出的icp就是多了第二步,以前Index filter是放在數據上操作的,現在5.6后多了第二步,因此效率提高了很多。

表的結構

	CREATE TABLE `left_test` (
  		`id` int(11) NOT NULL,
  		`a` int(11) DEFAULT NULL,
  		`b` int(11) DEFAULT NULL,
 	 	`c` int(11) DEFAULT NULL,
 	 	`d` int(11) DEFAULT NULL,
 		`e` int(11) DEFAULT NULL,
  		 PRIMARY KEY (`id`),
 		 KEY `m_index` (`a`,`b`,`c`)
	) ENGINE=InnoDB DEFAULT CHARSET=utf8

  且插入了100萬條數據。

sql的分析

 	select * from left_table where id=1。
	select * from left_table where id>1 and id<3

  使用了聚集索引,id為主鍵,那么這個表里面id則是聚集索引列,這條sql默認使用了聚集索引來搜索。
 

 	select * from left_table where a=1
	select * from left_table where a=1 and b=1
	select * from left_table where a=1 and b=1 and c=1

  使用聯合索引(a,b,c)。其中這些條件可以可以亂序,因為mysql的sql優化器會優化這些代碼

 	select * from left_table where a<1
	select * from left_table where a<1 and b<1
	select * from left_table where a<1 and b<1 and c<1

  對於現在mysql5.7中,只有小於等於和小於才會觸發索引。而大於則是無法觸發索引,且小於可以亂序(mysql優化器優化了),但是按照最左匹配原則。比如條件(b),(c),(b,c)組合就不行。

 	select * from left_table where b<1
	select * from left_table where b<1 and c<1
	select * from left_table where c<1 

  這個組合就用不到索引,因為不符合最左匹配原則。

 	select * from left_table where a>1
	select * from left_table where a>1 and b>1
	select * from left_table where a>1 and b>1 and c>1

  在mysql5.7這個版本,大於是不參與索引匹配的因此這些sql都沒參與索引匹配。

 	select * from left_table where a=1 and id=2

  這里面id是聚簇索引列,而a是個二級索引列,那么這個是用聚集索引列,不用(a,b,c)這個索引,因為對於mysql 5.7 innodb 這個版本一條sql里面索引只能用一條。至於用那個,則是mysql自身的算法選擇了。經過大量測試實驗,規則如下,如果索引列數據數據一模一樣,那么是誰先創建就選誰,如不一樣,那么誰占用的列越多,或者列的數據越復雜則選它。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM