MySQL在创建索引的时候如果不指定排序方式默认是按照升序排列,这也是B+tree的默认规则。在MySQL8之前只能是按照升序排列,即使指定了倒序也不会生效,但是MySQL8之后新加了倒序索引,在某些特定场景下使用可以有效提高查询性能。
索引反向扫描
很多时候我们会根据时间进行倒序排序,但是建立的索引都是正序,所以对于MySQL来说会反向扫描数据排序,这个过程对单条sql来说性能影响不大,所以不用太担心,但是某些场景来说会有些影响。
具体分析
- sql分析
如下这条第一条sql,是根据CT建立的desc倒序查询,查询的时候根据CT倒序,那么这个时候MySQL就不会进行排序的操作,直接返回结果。
如果根据asc正序查询,那么MySQL就需要执行排序过程,这个过程就是filesort,filesort是MySQL的一个排序策略。虽然利用了索引,但是并不能直接完成排序。
要确定排序是否使用了filesort,可以看执行计划,如果Extra出现了Using filesort,Using temporary那么就是使用了filesort。filesort策略会产生临时表,对内存和磁盘是有影响的。
create index A on user(CT desc)
select * from user order by CT desc
EXPLAIN select * from user order by CT desc
- 深度分页
MySQL的深度分页时致命的,这个是由它本身的特性决定的,如果在深度分页的同时再遇到索引反向扫描,会严重加剧性能的损耗。数据量过大,亲测10W的数据量,索引排序方式对性能的影响在3到5毫秒之间。
- 数据量过大
数据量过大的时候如果使用索引排序,可能会导致索引失效或者查询速度很慢,失效或者慢的原因可能就是反向扫描导致的,如果建立和排序方式匹配的索引就可以避免。这个数据量过大是个相对概念,需要根据服务器硬件资源综合考虑,不能单纯以数据量大小来衡量。
- 高并发对内存和磁盘的使用占比升高
上面说的第一点,如果出发了filesort,那么就会产生临时表,数据量小的时候占用内存,数据量大的时候会使用磁盘,如果并发又很大,那么对系统必然会造成影响,严重降低系统的性能。