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

索引分析

通过观察联邦索引的数据结构,可以明显看出索引是有序的,而使用索引进行排序利用了这一特性。

[En]

By observing the data structure of federated indexes, it is obvious that indexes are ordered, and sorting using indexes takes advantage of this feature.

MySQL 索引排序

我们来观察 a = 5 的这一段索引,很容易就能发现,在 a 确定的情况下, b 是有序的,但 c 是无序的。 a 和 b 命中索引, a 和 c 不命中索引

MySQL 索引排序

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

MySQL 索引排序

这就是老生常谈的 最佳左前缀原则 也叫 最左前缀匹配原则

因此,让已排序的项使用索引进行排序

[En]

Therefore, let the sorted items be sorted using the index

第一个条件就是:where条件+排序项符合 最佳左前缀原则

第二个条件:不能使用条件查询

这也可以通过观察联合指数得出结论。

[En]

This can also be concluded by observing the joint index.

a = 5 AND b >= 5 显然是无法保证 c 是有序的

MySQL 索引排序

结论

要让 order by 使用索引排序,需要 至少满足以下条件:

  1. where条件+排序项符合 最佳左前缀原则
  2. 不能使用条件查询

Original: https://www.cnblogs.com/weirwei/p/15846609.html
Author: weirwei
Title: MySQL 索引排序

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/507856/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球