MySQL 索引排序


表結構和數據

CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  `c` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
	KEY `idx_a_b_c` (`a`,`b`,`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
id a b c
1 1 5 3
2 5 3 3
3 4 5 9
4 2 6 1
5 4 3 2
6 5 5 5
7 1 2 1
8 5 5 8
9 5 3 9
10 5 5 1
11 5 7 7

SQL

explain select * from t where a = 5 order by c desc;
-- type:ref
-- key:idx_a_b_c
-- ref:const
-- Extra:Using where; Using index; Using filesort

explain select * from t where a = 5 order by b desc;
-- type:ref
-- key:idx_a_b_c
-- ref:const
-- Extra:Using where; Using index

explain select * from t where a = 5 and c = 5 order by b desc;
-- type:ref
-- key:idx_a_b_c
-- ref:const
-- Extra:Using where; Using index

explain select * from t where a = 5 and b = 5 order by c desc;
-- type:ref
-- key:idx_a_b_c
-- ref:const,const
-- Extra:Using where; Using index

explain select * from t where a = 5 and b >= 5 order by c desc;
-- type:range
-- key:idx_a_b_c
-- ref:NULL
-- Extra:Using where; Using index; Using filesort

索引分析

通過觀察聯合索引的數據結構,很明顯就能發現索引都是有序的,使用索引進行排序就是利用了這個特性。

我們來觀察 a = 5 的這一段索引,很容易就能發現,在 a 確定的情況下,b 是有序的,但c 是無序的。a 和 b 命中索引,a 和 c 不命中索引

a,b 都確定的情況下,c 是有序的。a,b,c 命中索引

這就是老生常談的 最佳左前綴原則 也叫 最左前綴匹配原則

因此,要讓排序項使用索引進行排序

第一個條件就是:where條件+排序項符合最佳左前綴原則

第二個條件:不能使用條件查詢

這個也可以通過觀察聯合索引得出結論

a = 5 AND b >= 5 顯然是無法保證 c 是有序的

結論

要讓order by 使用索引排序,需要至少滿足以下條件:

  1. where條件+排序項符合最佳左前綴原則
  2. 不能使用條件查詢


免責聲明!

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



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