本文简单介绍下用法,并分析下对应的代码实现
以下基于当前最新MySQL8.0.13版本
其实对应的语法一直是存在的,只是没有做具体的实现,直到8.0版本才真正实现,使用也很简单,在创建索引时,对索引列加asc/desc关键字,举个简单的例子:
如上例,可以看到指定不同的索引给出的结果顺序也是不一样的。
上例中可以看到explain的结果中没有filesort, 而在之前的版本中对于这样的sql是需要进行排序的。
- Descending index 无法使用change buffer
- GROUP BY不在隐式的保证顺序性,只有明确的指定asc/desc,才去确保顺序
笔者主要工作是在innodb引擎,对server层不甚了解,本文也主要关注innodb的改动。实际上这个特性的改动主要在server层的优化器和执行器,对于innodb来说,尽管数据存储发生了变化,但改动反而很少。
数据词典: 索引上的列属性被持久化到数据词典表(dd::Index)
key_rec_cmp: 比较的两个key不是大小关系,而是在索引上的前后关系,因此需要考虑键值列上是asc还是desc的 对于range查询,在之前的版本中总是min_Key被传到innodb作为search_tuple来定位btree,但如果是descending index,则需要选择max_key来作为search tuple (ref: SEL_ARG::get_min_flag(), SEL_ARG::get_max_flag(), SEL_ROOT::store_min_key)
InnoDB record compare: 为了支持这个特性,innodb的改动实际上并不大,大部分代码都是没有变化的,这主要是因为InnoDB使用了统一的比较函数来决定key值位置,索引对象传递到底层的比较函数中,以获取是否存在descending column.
相关函数: