Mysql序列(七)—— order by优化
前言
在mysql中满足order by的处理方式有两种:
- 让索引满足排序,即扫描有序索引然后再找到对应的行结果,这样结果即是有序;
- 使用索引查询出结果或者扫描表得到结果然后使用filesort排序;
filesort排序:是针结果在内存中进行排序,如果待排结果较大,mysql可能会产生临时文件输入输出到磁盘。
所以order by的优化思路
- 优先使用索引满足排序;
- 如果实在满足不了,再优化filesort排序;
使用索引满足order by规律总结
一般where子句的条件查询,大部分条件查询都会使用索引,如果这时加上order by索引生效,只要通过扫描索引即可完成排序,避免了额外的filesort的开销。
In some cases, MySQL may use an index to satisfy an ORDER BY clause and avoid the extra sorting involved in performing a filesort operation.
mysql官方手册描述:
在一些情况下,mysql可能会使用索引满足order by子句,从而避免了使用filesort操作进行的额外排序。
让order by使用索引进行排序时,并不一定需要order by子句中的列完全匹配索引,只要索引中未使用的部分和除了order by列的额外列都在where子句中作为常量匹配,order by仍然可能会使用索引实现排序。
在order by是否使用索引进行排序,都得依赖优化器决定使用索引是否比不使用索引更加高效
下面就总结下order by使用索引排序的几种情况:
- 如果select的结果是索引列的一部分(即覆盖索引),且order by按照索引的列进行排序,这种情况会扫描整个索引作为返回结果且都不用查询行,同时也使用索引进行排序。如:
create index idx_id_name on table_name (id, name);
// 因为id,name组成联合索引——已经有序,只要扫描整个idx_id_name,获取name即是有序
select name from table_name order by id;
但是这样就会使用文件排序:
// 虽然这里会使用覆盖索引,但是mysql会对查询出的结果做文件排序
// 因为扫描索引idx_id_name,得出的id不一定是按照name有序
// idx_id_name只能保证对id是有序
select id from table_name order by name;
- 按照完整索引排序,查询所有表行。如:
create index idx_name on table_name (name);
select * from order by name;
以上情况理论上按照使用索引实现排序。但是查询结果包含了其他的非索引列,所以优化器会抉择扫描整个有序索引然后再按需查找所有行是不是比扫描总个表使用filesort哪种方式更廉价。
- 使用索引一部分列作为where条件常量,另一个部分列作为order by排序,查询所有行。如:
// id,name组成联合索引,在id值为常量的索引中是按照name排序
create index idx_id_name on talbe_name (id, name);
select * from where id = constant order by name;
因为这里id是常量,所以按照where条件按照索引idx_id_name查找出的匹配结果行肯定在name上有序。这里影响是否使用索引满足排序的因素在于优化器判断按照id在扫描idx_id_name是比表扫描更廉价。
从以上的几种情况中可以看出两种影响是否使用索引完成排序的因素:
使用扫描索引找出匹配的结果行是否比全表扫描找出结果带来更大的性能收益。如果用来全表扫描,那么肯定不会使用filesort;
order by排序的列和where的条件的列索引使用上是否契合。如果按照where条件中索引匹配找到的结果,刚好就是按照order by排序的那么,索引查找过程也就完成了order by过程;如果不契合,即是使用了索引找到了匹配结果,任然需要filesort阶段完成排序。如果是单列索引,那么where需要和order by列上保持一致,如果是联合索引,where条件中使用索引列前缀部分,order by使用后半部分;
下面再看一些索引不满足order by的情况
- order by中使用了不同的索引进行排序
SELECT * FROM t1 ORDER BY key1, key2;
- 混合使用不同的顺序
SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;
- 用于检索结果行的索引和order by索引不是一个
SELECT * FROM t1 WHERE key2=constant ORDER BY key1;
使用filesort满足order by
If an index cannot be used to satisfy an ORDER BY clause, MySQL performs a filesort operation that reads table rows and sorts them. A filesort constitutes an extra sorting phase in query execution.
如果索引不能满足order by,mysql将会执行filesort操作。filesort操作是读取表行,然后在排序它们。在查询中filesort构成了一个额外的排序阶段。
To obtain memory for filesort operations, the optimizer allocates a fixed amount of sort_buffer_size bytes up front. Individual sessions can change the session value of this variable as desired to avoid execessive memory use, or to allocate more memory as necessary.
为了能够执行filesort操作,优化器需要提前分配固定数量的内存,每个大小由sort_buffer_size参数决定。
A filesort operation uses temporary disk files as necessary if the result set is too large to fit in memory.
当结果集太大不能完全放入内存时,filesort操作会使用零时的磁盘文件进行换入换出。
filesort调优策略:
- 增大sort_buffer_size值,让其足够放下结果集,以便在内存中完成filesort;
- 增大read_rnd_buffer_size,以便更多行被一次读出;
判断order by使用了哪种方式
With EXPLAIN (see Section 8.8.1, “Optimizing Queries with EXPLAIN”), you can check whether MySQL can use indexes to resolve an ORDER BY clause:
- If the Extra column of EXPLAIN output does not contain Using filesort, the index is used and a filesort is not performed.
- If the Extra column of EXPLAIN output contains Using filesort, the index is not used and a filesort is performed.
使用explain,可以检测mysql使用了索引还是是用filesort完成order by:
- 如果explain的extra中有using filesort,那么表示使用了filesort;
- 如果没有filesort,表示使用了index;
总结
order by优化的步骤:
- 尽量让index方式完成order by:如何where和order by相同列则使用单索引列;如果不同使用联合索引;
- 无法使用时,对filesort方式进行调优;
参考
ORDER BY Optimization
Mysql order by与limit混用陷阱
mysql 大数据量分页优化
Mysql序列(七)—— order by优化的更多相关文章
- Mysql查询优化汇总 order by优化例子,group by优化例子,limit优化例子,优化建议
Mysql查询优化汇总 order by优化例子,group by优化例子,limit优化例子,优化建议 索引 索引是一种存储引擎快速查询记录的一种数据结构. 注意 MYSQL一次查询只能使用一个索引 ...
- MySql学习(七) —— 查询性能优化 深入理解MySql如何执行查询
本篇深入了解查询优化和服务器的内部机制,了解MySql如何执行特定查询,从中也可以知道如何更改查询执行计划,当我们深入理解MySql如何真正地执行查询,明白高效和低效的真正含义,在实际应用中就能扬长避 ...
- MySQL性能优化,MySQL索引优化,order by优化,explain优化
前言 今天我们来讲讲如何优化MySQL的性能,主要从索引方面优化.下期文章讲讲MySQL慢查询日志,我们是依据慢查询日志来判断哪条SQL语句有问题,然后在进行优化,敬请期待MySQL慢查询日志篇 建表 ...
- Mysql group by,order by,dinstict优化
1.order by优化 2.group by优化 3.Dinstinct 优化 1.order by优化 实现方式: 1. 根据索引字段排序,利用索引取出的数据已经是排好序的,直接返回给客户端: 2 ...
- mysql实战优化之六:Order by优化 sql优化、索引优化
在MySQL中的ORDER BY有两种排序实现方式: 1.利用有序索引获取有序数据 2.文件排序 在使用explain分析查询的时候,利用有序索引获取有序数据显示Using index.而文件排序显示 ...
- MySQL性能优化(七):其它优化
原文:MySQL性能优化(七):其它优化 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/v ...
- mysql 序列与pg序列的比较
mysql序列(这里只谈innodb引擎): 在使用mysql的AUTO_INCREMENT时,使用AUTO_INCREMENT的字段必须建有索引,也可以为索引的一部分.当没有索引时会报错: ...
- mysql笔记03 查询性能优化
查询性能优化 1. 为什么查询速度会慢? 1). 如果把查询看作是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间.如果要优化查询,实际上要优化其子任务,要么消除其中一些子任务,要么减 ...
- php面试专题---Mysql索引原理及SQL优化
php面试专题---Mysql索引原理及SQL优化 一.总结 一句话总结: 注意:只写精品 1.为表设置索引要付出代价 是什么? 存储空间:一是增加了数据库的存储空间 修改插入变动索引时间:二是在插入 ...
随机推荐
- webpack本地开发起服务只能用localhost和端口号打开,不能用本地ip地址打开
这时候记得在webpack配置文件中 devServer中加host:'0.0.0.0' 或者在启动命令中加 --host 0.0.0.0
- 微信小程序使用websocket通讯的demo,含前后端代码,亲测可用
目录 0.概述websocket 1.app.js写法 2.后台写法 0.概述websocket (1) 个人总结:后台设置了websocket地址,服务器开启后等待有人去连接它. 一个客户端一打开就 ...
- 配置全文搜索引擎solr
前言 solr是apache下的一个子项目,用java编写基于Lucene开发的全文搜索服务器,不同于Lucene,solr一个完成的搜索服务器,提供了众多接口调用,而Lucene只是个工具包.如果用 ...
- 关于DFS的理解
DFS(深度优先搜索)相当于暴力寻找有效解的过程 如果把多种情况写成一个树的方式 那么DFS的实质就是遍历所有分枝来寻找最优解 而DFS中遍历所有解的方式采用了我们称之为回溯法的东西 如图所示 图中的 ...
- 流程及迭代驱动测试管理软件, itest 发布到开源中国
itest 源码已发布到码云 ,项目已被开源中国收录!详见 https://www.oschina.net/p/itest-cn 测试人自己开发,汇聚10年沉淀,独创流程驱动测试.度量展现测试人价值 ...
- Windows隐藏用户小技巧
0x01 前言 本文目的在于对于Windows账户访问与控制的技术理论进行分析与总结,熟悉了解Windows账户的特性及相关操作,并依此进行Windows账户的相关实验,进行实验记录与总结.通过本文记 ...
- MATLAB之指定文件读取与读取地址输出
一.读取指定文件夹下的指定格式文件 (1) 利用命令 uigetdir('','') 参数解释: uigetdir('所要打开的盘地址','对打开的弹出框进行描述') 例如:uigetdir('C:\ ...
- 2.3 Scala面向对象编程基础
一.类 1.类的定义 Unit表示什么都不返回 方法体最后一句的值,就是方法的返回值. 2.类成员的可见性 3.方法的定义方式 定义方法的时候加圆括号,调用时可以加圆括号c.getValue()也可以 ...
- python-下载网页链接
from urllib.request import urlretrieve url = 'http://images.jupiterimages.com/common/detail/27/68/22 ...
- LeetCode 204. Count Primes计数质数 (C++)
题目: Count the number of prime numbers less than a non-negative number, n. Example: Input: 10 Output: ...