一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情
最近在学MySQL,在官网发现了很多新特性,比如窗口函数、倒序索引、隐藏索引等等,今天来说下什么是倒序索引,其实看见这个名字大家应该都能够猜到这个是什么意思,前提是对索引有一定的了解,在mysql5.7里没有这个功能
举例说明:
给当前表class(10w数据)新增联合索引idx_className_monitor(className,monitor desc);,注意字段monitor是倒序,查看索引信息show index from class如下图:
执行如下SQL:explain select * from class order by className,monitor desc limit 10;执行计划如下:
MySQL5.7版本
我们可以看到在有联合索引的情况下,按照联合索引的最左匹配原则索引字段className和monitor字段应该是会生效的,扫描的行数将近10w,并且使用到了外部的文件排序,文件排序效率很慢,因为数据量太大,不能在buffer里排完,所以部分数据排序完成之后先写入到文件里,filesort排序算法分为两种MySQL在4.1之前是双路排序简单来说就是需要扫描两次磁盘取一次数据需要两次io扫描磁盘相对来说是消耗性能的,所以在MySQL4.1后有了单路排序,简单来说就是由两次io扫描变为了一次,这里使用了更多的buffer内存来存储数据减少一次io,虽然io次数减少但是对sort buffer内存有一定要求,使用可以适当提高sort_buffer_size的大小。
MySQL8.0版本
相同的条件我们在MySQL8.0里试下,创建索引,查看如下图:
我们在执行上面的SQL:explain select * from class order by className,monitor desc limit 10;MySQL8.0的执行计划如下:
可以看到执行计划字段
extra里没有输出其他内容,并且在扫描行数只有10条,相比之下MySQL8.0的倒序索引效率更快,如果想让MySQL5.7版本索引生效,就必须统一排序规则,要么是升序要么是降序,如下SQL:
explain select * from class order by className desc,monitor desc limit 10;
或者
explain select * from class order by className,monitor limit 10;
也就是说多个索引字段不能使用多个排序规则,必须统一,否则索引就会失效,其实对于order by排序或者group by分组来说如果不可以使用索引那么应该尽量不要在数据库层面去排序分组,放到业务层面代码进行操作更加快速。