mysql按升序创建索引_MySQL8新特性:降序索引详解
前言
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新特性:降序索引详解相关推荐
- 【java8新特性】——Stream API详解(二)
一.简介 java8新添加了一个特性:流Stream.Stream让开发者能够以一种声明的方式处理数据源(集合.数组等),它专注于对数据源进行各种高效的聚合操作(aggregate operation ...
- Spark 3.2.0 版本新特性 push-based shuffle 论文详解(二)背景和动机
前言 本文隶属于专栏<大数据技术体系>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见大数据技术体系 目录 Spark 3.2.0 ...
- Spark 3.2.0 版本新特性 push-based shuffle 论文详解(一)概要和介绍
前言 本文隶属于专栏<大数据技术体系>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见大数据技术体系 目录 Spark 3.2.0 ...
- mysql按升序创建索引_Mysql中的降序索引底层实现
什么是降序索引 大家可能对索引比较熟悉,而对降序索引比较陌生,事实上降序索引是索引的子集. 我们通常使用下面的语句来创建一个索引: 上面sql的意思是在t1表中,针对b,c,d三个字段创建一个联合索引 ...
- java8 stream遍历_Java8新特性:Stream流详解
1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel agg ...
- java lambda表达式详解_Java8新特性:Lambda表达式详解
在 Java 版本的历次更新迭代中,Java8 是一个特殊的存在,与以往的版本升级不同.我们对 Java8 似乎抱有更大的期待,因为它是 Java5 之后最重要的一次升级,提供了十多个新特性,其中 L ...
- H5的新特性及部分API详解
h5新特性总览 移除的元素 纯表现的元素: basefont.big.center.font等 对可用性产生负面影响的元素: frame.frameset.noframes 新增的API 语义: 能 ...
- oracle中pdb,Oracle 12C新特性-CDB和PDB 详解
最近看到好多人都在尝试Oracle中的12C新特性-容器数据库,今年3月Orcle推出了Release2版本,可以算是一个稳定版本了.下午着手尝试了一下,还是蛮不错得 1.前言 CDB与PDB是Ora ...
- java lambda表达式详解_java8新特性-Lambda表达式的详解(从0开始)
这几天复习了java8的一些新特性,作为一个从java5以来最具革命性的版本,一直没有来得及总结.本系列文章主要是从<java8实战>总结的.这是第一篇文章主要介绍java8的lambda ...
最新文章
- 【Java代码实现】递归两大经典问题-----“汉诺塔问题” 与 “青蛙跳台阶问题” 讲解
- 手机访问同局域网下的PC中Tomcat中的项目
- 《社交网站界面设计(原书第2版)》——2.11 提问
- 笔记本电脑如何强制关机_如果你的MacBook一直关机,该怎么办?
- toolBar——工具栏
- 安卓打开本应用的应用信息界面的代码
- 2012年--麦思博--12月7-9日全球软件案例研究峰会讲师ppt
- openwrt1907 mt7621配置DDR自适应
- 3000字神经网络论文
- 编译原理实验一:单词的词法分析程序设计
- python编写鸡兔同笼程序_编写程序,分享解鸡兔同笼问题? 用Python分享多笼鸡兔同笼...
- deepin 设置wifi热点
- 2015年总结,平平淡淡的一年.
- 【神经网络】梯度消失与梯度爆炸问题
- 【超详细】使用Oracle VM VirtualBox 搭建一个Linux虚拟机
- windows 组策略
- x86架构下的安卓虚拟化
- python用户登录a_python实现用户登录
- 语音处理的算法和方法研究(Matlab代码实现)
- 解决:harmony鸿蒙设备获取udid(真机)
热门文章
- VC++ inline内联函数的作用解决方案
- python 调用c++回调char*
- Python中的map()函数和reduce()函数的用法
- Matlab 方括号“[ ]”的作用
- 南昌航空航天c语言试卷,2016年南昌航空大学软件学院程序设计复试笔试仿真模拟题...
- java中的localDate类_java8-LocalDate类
- python turtle基本语法_Python 基础语法-turtle篇
- 11旋转编码器原理图_plc编程入门:浅谈编码器的工作原理!
- maven私服的配置使用
- linux上寻找并杀死僵尸进程