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.为表设置索引要付出代价 是什么? 存储空间:一是增加了数据库的存储空间 修改插入变动索引时间:二是在插入 ...
随机推荐
- redis笔记2
分布式锁的实现 锁是用来解决什么问题的; 一个进程中的多个线程,多个线程并发访问同一个资源的时候,如何解决线程安全问题. 一个分布式架构系统中的两个模块同时去访问一个文件对文件进行读写操作 多个应用对 ...
- android studio学习----gradle多渠道打包
由于国内Android市场众多渠道,为了统计每个渠道的下载及其它数据统计,就需要我们针对每个渠道单独打包,如果让你打几十个市场的包岂不烦死了,不过有了Gradle,这再也不是事了. 友盟多渠道打包 废 ...
- 七、union联合
Union:联合 作用:把2次或多次查询结果合并起来 案例(认识union):我想把商品价格大于5000元的和商品价格小于20元的商品都取出来 1.Select * from goods where ...
- Java结构讲解
Java结构有顺序结构.选择结构和循环结构. 顺序结构: 是Java的基本结构,除非特别说明,否则按顺序一句一句执行:也是最简单的结构:它是任何一个算法都离不开的一种基本算法结构. 选择结构: 1.i ...
- django中添加新的filter
给模板传递了一个字典,却发现无法在模板中直接通过key获得value. 查阅资料后,这个问题可以通过添加自定义的filter来解决. 首先在app目录下创建一个templatetags目录,并在它的下 ...
- 算法学习day01 栈和队列
1,设计一个算法利用顺序栈的基本运算判断一个字符串是否是回文 解题思路: 由于回文是从前到后和从后到前读都是一样的,所以只要将待判断的字符串颠倒 然后与原字符串相比较,就可以决定是否是回文了 ...
- Codeforces 1278F: Cards
题目传送门:CF1278F. 题意简述: 有 \(n\) 个独立随机变量 \(x_i\),每个随机变量都有 \(p = 1/m\) 的概率取 \(1\),有 \((1-p)\) 的概率取 \(0\). ...
- 《面向对象程序设计(java)》第十周学习总结
201871010115 马北<面向对象程序设计(java)>第十周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh ...
- 201871010117-石欣钰《面向对象程序设计(java)》第十五周学习总结
项目 内容 这个作业属于哪个课程 <任课教师博客主页链接>https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址>http ...
- 201871010135 张玉晶《面向对象程序设计(java)》第6-7周学习总结
201871010135 张玉晶<面向对象程序设计(java)>第6-7周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...