在MySQL8.0之前,索引定义中的DESC关键字被忽略.从MySQL8.0开始支持在定义索引时使用DESC。之前,可以对索引进行倒序扫描,但是有额外的性能损耗。现在, 利用降序索引,可以进行正向扫描,这样性能更好。
使用逆序索引有以下限制:
- 目前只支持InnoDB存储引擎。
- 逆序索引无法使用Change Buffer。
- 逆序索引无法使用MIN()/MAX()的查询优化。
- 逆序索引支持BTREE索引,不支持HASH索引、全文索引和空间索引。
如果order by中有两个字段,这两个字段在同一个索引中,那么这两个字段,在索引中必须是同向的,但是order by语句中的排序方向则可以不同。例如: 示例表结构:
CREATE TABLE `t11` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`c` int NOT NULL DEFAULT '0',
`d` int unsigned NOT NULL DEFAULT '0',
`f` int unsigned NOT NULL DEFAULT '0',
`e` int unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_cdf` (`c`,`d` DESC,`f`),
KEY `idx_d` (`d`)
) ENGINE=InnoDB AUTO_INCREMENT=2249057 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
示例查询1:
select * from t11 where c=5 order by d desc,f desc limit 0,5;
使用explain查看执行计划:
可以看到,虽然使用到了索引idx_cdf,但是在却无法使用索引进行排序,而是使用了filesort。
示例查询2:
select * from t11 where c=5 order by d asc,f desc limit 0,5;
使用explain查看执行计划:
可以看到,使用到了索引查询,也使用到了索引排序,只不过,扫描索引时是Backward index scan,即是逆向扫描,而非正向。
示例查询3:
select * from t11 where c=5 order by d desc,f asc limit 0,5;
使用explain查看执行计划:
上面的语句,使用到了索引查询,也使用到了索引排序,且是正向扫描。