MySQL有两种方式可以生成有序的结果:通过排序操作;或者按索引顺序扫描;如果explain出来的type列的值为index,则说明MySQL使用了索引扫描来做排序。

扫描索引本身是很快的,因为只需要从一条索引记录移动到紧接着的下一条记录。但如果索引不能覆盖查询所需的全部列,那就不得不每扫描一条索引记录就得回表查询一次对应的行了。这基本上都是随机I/O,因此按索引顺序读取数据的速度通常要比顺序地全表扫描慢,尤其是在I/O密集型的工作负载时。

MySQL可以使用同一个索引既满足排序,又用于查找行。因此,如果可能,设计索引时应该尽可能地同时满足这两个任务,这样是最好的。

只有当索引的顺序和ORDER BY子句的顺序完全一致,并且所有列的排序方向都一样时,MySQL才能使用索引结果来做排序。如果查询需要关联多张表,则只有当ORDER BU子句引用的字段全部为第一个表时,才能使用索引做排序。ORDER BY子句和查找型查询的限制是一样的:需要满足索引的最左前缀的要求;否则,MySQL都需要执行排序操作,而无法利用索引排序。

有一种情况ORDER BY子句可以不满足索引的最左前缀的要求,就是前导列为常量的时候。如果WHERE子句或者JOIN子句中对这些列指定了常量,就可以弥补索引的不足。

如,

CREATE TABLE `sakila` (

`rental_id` int(10) NOT NULL AUTO_INCREMENT,

`rental_date` date DEFAULT NULL,

`inventory_id` int(10) DEFAULT NULL,

`customer_id` int(10) DEFAULT NULL,

`staff_id` int(10) DEFAULT NULL,

PRIMARY KEY (`rental_id`),

UNIQUE KEY `rental_date` (`rental_date`,`inventory_id`,`customer_id`) USING BTREE,

KEY `inventory` (`inventory_id`) USING BTREE,

KEY `customer` (`customer_id`) USING BTREE,

KEY `staff` (`staff_id`) USING BTREE

) ENGINE=InnoDB ;

MySQL可以使用rental_date索引为下面的查询做排序,从explain中可以看到有没有出现文件排序操作:

explain select rental_id,staff_id from sakila where rental_date='2019-10-10' order by inventory_id,customer_id

即使order by子句不满足索引的最前左缀的要求,也可以哟用于查询排序,这是因为索引的第一列被指定为一个常数。

还有更多可以使用索引做排序的查询示例。下面这个查询可以利用索引排序,是因为查询为索引的第一列提供了常量条件,而是用第二列进行排序,将两列组合在一起,就形成了索引的最左前缀:

explain select rental_id,staff_id from sakila where rental_date='2019-10-10' order by inventory_id desc

explain select rental_id,staff_id from sakila where rental_date > '2019-10-10' order by rental_date,inventory_id

这列查询则不能使用索引排序:

1、排序方向不同,而索引列是正序排序

... where rental_date='2019-10-10' order by inventory_id desc,customer_id asc

2、order by子句引用了一个不再索引中的列

... where rental_date='2019-10-10' order by inventory_id desc,staff_id

3、where和order by中的列无法组合成索引的最左前缀

... where rental_date='2019-10-10' order by customer_id asc

4、wehre子句在索引列的第一列上市范围条件,所以MySQL无法使用索引的其余列

... where rental_date>'2019-10-10' order by inventory_id desc,customer_id

5、在inventory_id列上有多个等于条件。对于排序来说,这也是一种范围查询

... where rental_date='2019-10-10' and inventory_id in(1,2) order by customer_id

mysql使用索引扫描做排序_「Mysql索引原理(八)」使用索引扫描做排序相关推荐

  1. list排序_「肘后备急码」- C#对象List排序

    经常遇到要对一个对象List排序的要求,我觉得以下是最方便的方法. 核心代码 主要是实现System.Collections.IComparer这个接口 完整示例 备注 里面Person我用的是str ...

  2. mysql所选路径已经存在_「mysql第二次安装不了」mysql安装失败怎么清理干净?

    很多朋友装mysql数据库时出现无法安装的情况,更可怕的是删除相关文件仍然无法安装,很伤脑筋,相信很多朋友都有过这种经历. 其实导致数据无法安装的原因大多数是因为之前安装的Mysql数据没有卸载干净, ...

  3. mysql支持事务的储存引擎_「mysql事务与mysql储存引擎」- 海风纷飞Blog

    事务概念及存储引擎 1.0 为何要事务? 先来看一个场景,银行转账汇款: 李彦宏和周鸿祎天天打架,现在让李彦宏给周鸿祎转款1000 元 设计如下表 account表 编号(id)用户名(user)金额 ...

  4. sql datetime 排序_超全的数据库建表/SQL/索引规范,建议贴在工位上!

    作者:浮雷来源:juejin.im/post/6871969929365553165 「背景」 因为工作岗位的原因,负责制定了关于后端组数据库的规约规范,作为所有产品线的规范,历经几版的修改,最终形成 ...

  5. 平安夜,还做那只「花好夜猿」吗?

    ????圣诞平安夜???? 淘小橙,一如既往的实力宠粉???? 咳咳!发福利之前 要给大家科普下打开平安夜的"正确姿势"???? 希望我的小粉们不做那只「花好夜猿」 我只能帮你们到 ...

  6. mysql的覆盖索引原理_「Mysql索引原理(七)」覆盖索引

    通常大家都会根据查询的WHERE条件来创建合适的索引,不过这只是索引优化的一个方面.设计优秀的索引应该考虑到整个查询,而不单单是WHERE条件部分.索引确实是一种查找数据的高效方式,但是MySQL也可 ...

  7. 如何给mysql表添加百万条数据_给mysql一百万条数据的表添加索引

    直接alter table add index 添加索引,执行一个小时没反应,并且会导致锁表:故放弃该办法,最终解决办法如下: 一.打开mysql 命令行客户端 这里我们那可以看到导出的数据文件所存放 ...

  8. mysql第五章项目二_高性能MySQL笔记 第5章 创建高性能的索引

    索引(index),在MySQL中也被叫做键(key),是存储引擎用于快速找到记录的一种数据结构.索引优化是对查询性能优化最有效的手段. 5.1 索引基础 索引的类型 索引是在存储引擎层而不是服务器层 ...

  9. mysql按 当前时间和规定时间大小排序_为什么 MySQL 使用 B+ 树· Why#x27;s THE Design?(009)...

    原文链接:https://draveness.me/whys-the-design-mysql-b-plus-tree 为什么 MySQL 使用 B+ 树 · Why's THE Design?​dr ...

最新文章

  1. OKR怎么使用比较好?
  2. 编写一个程序,它从标准输入(终端)读取C源代码,并验证所有的花括号都正确的成对出现。...
  3. 秒杀系统架构解密与防刷设计 - 高可用架构系列
  4. 转:ext2文件系统详解
  5. 视频专辑:JAVA语言入门视频教程
  6. CentOS系统更换yum源(repomd.xml not found解决方案)
  7. JMetro“ Metro”选项卡,Java的TreeView和ContextMenu(JavaFX)
  8. C#中判断服务器图片是否存在
  9. oracle--索引--
  10. hdu 1059 (多重背包) Dividing
  11. Operation,Tensor, Variable
  12. 如何把握云计算时代风口 怎么能掌握云计算技术
  13. retroarch java,跨平台模拟器 RetroArch
  14. 快排和归并排序--快排处理第k大元素
  15. 【AI测试】人工智能测试整体介绍——第六部分
  16. 【小强推歌】---法文歌曲下载
  17. 空中群体机器人研究综述
  18. 三级网络技术第三题总结
  19. 5 个免费练习黑客技术的网站!
  20. 【解决】应用程序无法正常启动(0xc000007b)。请单击“确定”关闭应用程序。

热门文章

  1. 中国大数据企业排行榜V6.0- 5 年后再去看看中几个大数据公司的发展状况
  2. mysql 不join的原因
  3. jQuery源码分析系列 : 整体架构
  4. 【FPGA-F3】阿里云FAAS平台,极大简化FPGA开发部署流程
  5. express 对数据库数据增删改查
  6. scikit-learn 入门
  7. idea代码调试debug篇
  8. C#对Microsoft.VisualBasic My对象兰台妙选
  9. Python的matplotlib(2)
  10. 基于Html5的移动端开发框架的研究