MySQL利用索引排序實踐

要使用多列索引(聯合索引),須要知足最左原則,where條件必須和索引的順序一致,若是隻用到單列則必須是最左列。只有當索引的列順序和ORDER BY子句的順序徹底一致,而且全部列的排序方向(倒序或正序)都同樣時,MySQL纔可以使用索引來對結果作排序。若是查詢須要關聯多張表,則只有當ORDER BY子句引用的字段所有爲第一個表時,才能使用索引作排序。也須要知足索引的最左前綴要求(例外:前導列爲常量的時候)。--摘自《高性能MySQL》
建以下表測試索引排序(版本5.7.17),聯合索引:test_realname_sex_age_index,單列索引:sex_index、age_index,( 一次查詢只能利用一個索引
CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `realname` varchar(10) NOT NULL DEFAULT '',
  `sex` tinyint(4) NOT NULL DEFAULT '0',
  `age` tinyint(4) NOT NULL DEFAULT '0',
  `job` varchar(10) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `test_realname_sex_age_index` (`realname`,`sex`,`age`),
  KEY `sex_index` (`sex`),
  KEY `age_index` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

聯合索引測試

使用兩種不一樣的排序方向排序
能利用索引排序
EXPLAIN SELECT * FROM test WHERE realname = 'wen' ORDER BY sex DESC ,age DESC;
不能利用聯合索引排序,由於sex和age的排序方向不一致
EXPLAIN SELECT * FROM test WHERE realname = 'wen' ORDER BY sex DESC ,age ASC ;
用了一個不在索引中的列
  • 不能,由於job列不在聯合索引內
EXPLAIN SELECT * FROM test WHERE realname = 'wen' ORDER BY sex,job;
where order by中的列沒法組合成索引的最左前綴
  • 不能,realname和age不知足最左原則
EXPLAIN SELECT * FROM test WHERE realname = 'wen' ORDER BY age;
EXPLAIN SELECT * FROM test WHERE realname = 'wen' ORDER BY sex;
  1. 查詢在索引第一列上是範圍條件
  • 不能
EXPLAIN SELECT * FROM test WHERE realname > 'wen' ORDER BY sex,age;
EXPLAIN SELECT * FROM test WHERE realname BETWEEN 'wen1' AND 'wen2' ORDER BY sex,age;
索引上有多個等於條件(in)
  • 不能
EXPLAIN SELECT * FROM test WHERE realname = 'wen' AND sex IN (1,2) ORDER BY  age;
前導列不爲常量,而且使用範圍條件
不能
EXPLAIN SELECT * FROM test WHERE realname > 'qqq' ORDER BY sex;
能,知足最左原則
EXPLAIN SELECT * FROM test WHERE realname = 'qqq' ORDER BY sex;
  • 選擇合適的索引順序
通常來講:將選擇性最高的列放到索引的最前列。計算方法
SELECT count(DISTINCT realname)/COUNT(*) realname_selectivity,count(DISTINCT sex)/COUNT(*) sex_selectivity,count(DISTINCT age)/COUNT(*) age_selectivity,count(*) total FROM test;

使用單索引排序的例子

where條件和排序的列不一致
不能使用索引排序
EXPLAIN SELECT * FROM test WHERE sex = 1 ORDER BY age;
使用了範圍
EXPLAIN SELECT * FROM test WHERE age > 17 ORDER BY age;
沒有where條件直接排序
主鍵能夠排序
EXPLAIN SELECT * FROM test ORDER BY id;
不能
EXPLAIN SELECT * FROM test ORDER BY sex;
相關文章
相關標籤/搜索