前言

MySQL 8.0终于支持降序索引了。其实,从语法上,MySQL 4就支持了,但正如官方文档所言,"they are parsed but ignored",实际创建的还是升序索引。

无图无真相,同一个建表语句,看看MySQL 5.7和8.0的区别。

create table slowtech.t1(c1 int,c2 int,index idx_c1_c2(c1,c2 desc));

MySQL 5.7

mysql> show create table slowtech.t1\G

*************************** 1. row ***************************

Table: t1

Create Table: CREATE TABLE `t1` (

`c1` int(11) DEFAULT NULL,

`c2` int(11) DEFAULT NULL,

KEY `idx_c1_c2` (`c1`,`c2`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1

row in set (0.00 sec)

虽然c2列指定了desc,但在实际的建表语句中还是将其忽略了。再来看看MySQL 8.0的结果。

mysql> show create table slowtech.t1\G

*************************** 1. row ***************************

Table: t1

Create Table: CREATE TABLE `t1` (

`c1` int(11) DEFAULT NULL,

`c2` int(11) DEFAULT NULL,

KEY `idx_c1_c2` (`c1`,`c2` DESC)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

row in set (0.00 sec)

c2列还是保留了desc子句。

降序索引的意义

如果一个查询,需要对多个列进行排序,且顺序要求不一致。在这种场景下,要想避免数据库额外的排序-“filesort”,只能使用降序索引。还是上面这张表,来看看有降序索引和没有的区别。

MySQL 5.7

mysql> explain select * from slowtech.t1 order by c1,c2 desc;

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------------+

| 1 | SIMPLE | t1 | NULL | index | NULL | idx_c1_c2 | 10 | NULL | 1 | 100.00 | Using index; Using filesort |

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-----------------------------+

row in set, 1 warning (0.00 sec)

MySQL 8.0

mysql> explain select * from slowtech.t1 order by c1,c2 desc;

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+

| 1 | SIMPLE | t1 | NULL | index | NULL | idx_c1_c2 | 10 | NULL | 1 | 100.00 | Using index |

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+

row in set, 1 warning (0.00 sec)

两者的对比可以看出,MySQL 8.0因为降序索引的存在,避免了“filesort”。

这其实是降序索引的主要应用场景。如果只对单个列进行排序,降序索引的意义不是太大,无论是升序还是降序,升序索引完全可以应付。还是同样的表,看看下面的查询。

MySQL 5.7

mysql> explain select * from slowtech.t1 order by c1;

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+

| 1 | SIMPLE | t1 | NULL | index | NULL | idx_c1_c2 | 10 | NULL | 1 | 100.00 | Using index |

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+

row in set, 1 warning (0.00 sec)

mysql> explain select * from slowtech.t1 order by c1 desc;

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+

| 1 | SIMPLE | t1 | NULL | index | NULL | idx_c1_c2 | 10 | NULL | 1 | 100.00 | Using index |

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+

row in set, 1 warning (0.00 sec)

虽然c1是升序索引,但在第二个查询中,对其进行降序排列时,并没有进行额外的排序,使用的还是索引。在这里,大家容易产生误区,以为升序索引就不能用于降序排列,实际上,对于索引,MySQL不仅支持正向扫描,还可以反向扫描。反向扫描的性能同样不差。以下是官方对于降序索引的压测结果,测试表也只有两列(a,b),建了一个联合索引(a desc,b asc),感兴趣的童鞋可以看看,http://mysqlserverteam.com/mysql-8-0-labs-descending-indexes-in-mysql/

而在8.0中,对于反向扫描,有一个专门的词进行描述“Backward index scan”。

mysql> explain select * from slowtech.t1 order by c1;

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+

| 1 | SIMPLE | t1 | NULL | index | NULL | idx_c1_c2 | 10 | NULL | 1 | 100.00 | Using index |

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+-------------+

row in set, 1 warning (0.00 sec)

mysql> explain select * from slowtech.t1 order by c1 desc;

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+----------------------------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+----------------------------------+

| 1 | SIMPLE | t1 | NULL | index | NULL | idx_c1_c2 | 10 | NULL | 1 | 100.00 | Backward index scan; Using index |

+----+-------------+-------+------------+-------+---------------+-----------+---------+------+------+----------+----------------------------------+

row in set, 1 warning (0.00 sec)

终于不再对group by进行隐式排序

由于降序索引的引入,MySQL 8.0再也不会对group by操作进行隐式排序。

下面看看MySQL 5.7和8中的测试情况

create table slowtech.t1(id int);

insert into slowtech.t1 values(2);

insert into slowtech.t1 values(3);

insert into slowtech.t1 values(1);

MySQL 5.7

mysql> select * from slowtech.t1 group by id;

+------+

| id |

+------+

| 1 |

| 2 |

| 3 |

+------+

rows in set (0.00 sec)

mysql> explain select * from slowtech.t1 group by id;

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+

| 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | Using temporary; Using filesort |

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+

row in set, 1 warning (0.00 sec)

“Using filesort”,代表查询中有排序操作,从结果上看,id列确实也是升序输出。

MySQL 8.0

mysql> select * from slowtech.t1 group by id;

+------+

| id |

+------+

| 2 |

| 3 |

| 1 |

+------+

rows in set (0.00 sec)

mysql> explain select * from slowtech.t1 group by id;

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------+

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------+

| 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | Using temporary |

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------+

row in set, 1 warning (0.01 sec)

不仅结果没有升序输出,执行计划中也没有“Using filesort”。

可见,MySQL 8.0对于group by操作确实不再进行隐式排序。

从5.7升级到8.0,依赖group by隐式排序的业务可要小心咯。

参考文档

http://mysqlserverteam.com/mysql-8-0-labs-descending-indexes-in-mysql/

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

mysql按升序创建索引_MySQL8新特性:降序索引详解相关推荐

  1. 【java8新特性】——Stream API详解(二)

    一.简介 java8新添加了一个特性:流Stream.Stream让开发者能够以一种声明的方式处理数据源(集合.数组等),它专注于对数据源进行各种高效的聚合操作(aggregate operation ...

  2. Spark 3.2.0 版本新特性 push-based shuffle 论文详解(二)背景和动机

    前言 本文隶属于专栏<大数据技术体系>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见大数据技术体系 目录 Spark 3.2.0 ...

  3. Spark 3.2.0 版本新特性 push-based shuffle 论文详解(一)概要和介绍

    前言 本文隶属于专栏<大数据技术体系>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见大数据技术体系 目录 Spark 3.2.0 ...

  4. mysql按升序创建索引_Mysql中的降序索引底层实现

    什么是降序索引 大家可能对索引比较熟悉,而对降序索引比较陌生,事实上降序索引是索引的子集. 我们通常使用下面的语句来创建一个索引: 上面sql的意思是在t1表中,针对b,c,d三个字段创建一个联合索引 ...

  5. java8 stream遍历_Java8新特性:Stream流详解

    1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel agg ...

  6. java lambda表达式详解_Java8新特性:Lambda表达式详解

    在 Java 版本的历次更新迭代中,Java8 是一个特殊的存在,与以往的版本升级不同.我们对 Java8 似乎抱有更大的期待,因为它是 Java5 之后最重要的一次升级,提供了十多个新特性,其中 L ...

  7. H5的新特性及部分API详解

    h5新特性总览 移除的元素 纯表现的元素: basefont.big.center.font等  对可用性产生负面影响的元素: frame.frameset.noframes 新增的API 语义: 能 ...

  8. oracle中pdb,Oracle 12C新特性-CDB和PDB 详解

    最近看到好多人都在尝试Oracle中的12C新特性-容器数据库,今年3月Orcle推出了Release2版本,可以算是一个稳定版本了.下午着手尝试了一下,还是蛮不错得 1.前言 CDB与PDB是Ora ...

  9. java lambda表达式详解_java8新特性-Lambda表达式的详解(从0开始)

    这几天复习了java8的一些新特性,作为一个从java5以来最具革命性的版本,一直没有来得及总结.本系列文章主要是从<java8实战>总结的.这是第一篇文章主要介绍java8的lambda ...

最新文章

  1. 【Java代码实现】递归两大经典问题-----“汉诺塔问题” 与 “青蛙跳台阶问题” 讲解
  2. 手机访问同局域网下的PC中Tomcat中的项目
  3. 《社交网站界面设计(原书第2版)》——2.11 提问
  4. 笔记本电脑如何强制关机_如果你的MacBook一直关机,该怎么办?
  5. toolBar——工具栏
  6. 安卓打开本应用的应用信息界面的代码
  7. 2012年--麦思博--12月7-9日全球软件案例研究峰会讲师ppt
  8. openwrt1907 mt7621配置DDR自适应
  9. 3000字神经网络论文
  10. 编译原理实验一:单词的词法分析程序设计
  11. python编写鸡兔同笼程序_编写程序,分享解鸡兔同笼问题? 用Python分享多笼鸡兔同笼...
  12. deepin 设置wifi热点
  13. 2015年总结,平平淡淡的一年.
  14. 【神经网络】梯度消失与梯度爆炸问题
  15. 【超详细】使用Oracle VM VirtualBox 搭建一个Linux虚拟机
  16. windows 组策略
  17. x86架构下的安卓虚拟化
  18. python用户登录a_python实现用户登录
  19. 语音处理的算法和方法研究(Matlab代码实现)
  20. 解决:harmony鸿蒙设备获取udid(真机)

热门文章

  1. VC++ inline内联函数的作用解决方案
  2. python 调用c++回调char*
  3. Python中的map()函数和reduce()函数的用法
  4. Matlab 方括号“[ ]”的作用
  5. 南昌航空航天c语言试卷,2016年南昌航空大学软件学院程序设计复试笔试仿真模拟题...
  6. java中的localDate类_java8-LocalDate类
  7. python turtle基本语法_Python 基础语法-turtle篇
  8. 11旋转编码器原理图_plc编程入门:浅谈编码器的工作原理!
  9. maven私服的配置使用
  10. linux上寻找并杀死僵尸进程