MySQL 8.0现在支持降序索引(DESC,降序索引)。以前,可以以相反的顺序扫描ASC(升序)索引,但是会降低性能。通过使用降序索引,即使访问权限降序,也可以按升序扫描。考虑到成本,即使它是包括DESC的多列索引,优化器也会使用它。
同样的建表语句在5.7和8.0还是有区别的,5.7 c2列指定了desc,但在实际的建表语句中还是将其忽略了; MySQL 8.0 c2列还是保留了desc子句 ;
如果一个查询,需要对多个列进行排序,且顺序要求不一致。在这种场景下,要想避免数据库额外的排序-“filesort”,只能使用降序索引。
两者的对比可以看出,MySQL 8.0因为降序索引的存在,避免了“filesort”。优化器可以为每个ORDER BY子句执行前向索引扫描, 并且不需要使用 filesort操作。
如果只对单个列进行排序,降序索引并没有太大意义
c1是升序本身索引,但在第二个查询中,对其进行降序排列时,并没有进行额外的排序,使用的还是索引。
由于降序索引的引入,MySQL 8.0再也不会对group by操作进行隐式排序。
从上面可以看出 MySQL 5.7 “Using filesort”,代表查询中有排序操作,从结果上看,id列确实也是升序输出。MySQL 8.0 不仅结果没有升序输出,执行计划中也没有“Using filesort”。可以看出MySQL 8.0对于group by操作确实不再进行隐式排序。
使用降序索引必须符合以下条件
1、仅InnoDB存储引擎支持降序索引 ,但有以下限制
2、如果索引包含降序索引键列或主键包含降序索引列,则辅助索引不支持更改缓冲。该InnoDBSQL解析器不使用降序索引。对于InnoDB 全文搜索,这意味着FTS_DOC_ID不能将索引表的列上所需的索引定义为降序索引。
3、所有可用升序索引的数据类型均支持降序索引。
4、普通(非生成)列和生成的列(VIRTUAL和 STORED)都支持降序索引。
5、DISTINCT 可以使用包含匹配列的任何索引,包括降序的关键部分。
6、具有降序关键部分的索引不会用于MIN()/MAX()优化调用聚合函数但没有GROUP BY子句的查询。
7、支持降序索引,BTREE但不支持 HASH 索引。FULLTEXT或SPATIAL 索引不支持降序索引。