Using temporary与Using filesort
通过explain
查看sql的执行计划时,Extra
字段的值往往会看到Using where; Using index; Using temporary; Using filesort
,其中此次重点关注Using temporary; Using filesort
。
Using temporary
Using temporary
表示由于排序没有走索引、使用union
、子查询连接查询、使用某些视图等原因(详见internal-temporary-tables),因此创建了一个内部临时表。注意这里的临时表可能是内存上的临时表,也有可能是硬盘上的临时表,理所当然基于内存的临时表的时间消耗肯定要比基于硬盘的临时表的实际消耗小。
查看sql执行时使用的是内存临时表还是硬盘临时表,需要使用如下命令:
mysql> show global status like '%tmp%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 0 |
| Created_tmp_files | 5 |
| Created_tmp_tables | 11 |
+-------------------------+-------+
3 rows in set
Created_tmp_tables表示mysql创建的内部临时表的总数(包括内存临时表和硬盘临时表);Created_tmp_disk_tables表示mysql创建的硬盘临时表的总数。
当mysql需要创建临时表时,选择内存临时表还是硬盘临时表取决于参数tmp_table_size和max_heap_table_size,内存临时表的最大容量为tmp_table_size
和max_heap_table_size
值的最小值,当所需临时表的容量大于两者的最小值时,mysql就会使用硬盘临时表存放数据。
用户可以在mysql的配置文件里修改该两个参数的值,两者的默认值均为16M。
tmp_table_size = 16M
max_heap_table_size = 16M
查看tmp_table_size
和max_heap_table_size
值:
mysql> show global variables like 'max_heap_table_size';
+---------------------+----------+
| Variable_name | Value |
+---------------------+----------+
| max_heap_table_size | 16777216 |
+---------------------+----------+
1 row in setmysql> show global variables like 'tmp_table_size';
+----------------+----------+
| Variable_name | Value |
+----------------+----------+
| tmp_table_size | 16777216 |
+----------------+----------+
1 row in set
Using filesort
如果问Using filesort
是什么意思,大多数人应该会回答“基于硬盘的排序”或者“数据太多不适合内存,所以在硬盘上排序”。然而这些解释是错误的。
Using filesort
仅仅表示没有使用索引的排序,事实上filesort
这个名字很糟糕,并不意味着在硬盘上排序,filesort
与文件无关。因此消除Using filesort
的方法就是让查询sql的排序走索引。
filesort
使用的算法是QuickSort
,即对需要排序的记录生成元数据进行分块排序,然后再使用mergesort方法合并块。其中filesort
可以使用的内存空间大小为参数sort_buffer_size的值,默认为2M。当排序记录太多sort_buffer_size
不够用时,mysql会使用临时文件来存放各个分块,然后各个分块排序后再多次合并分块最终全局完成排序。
mysql> show global variables like 'sort_buffer_size';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| sort_buffer_size | 262144 |
+------------------+--------+
1 row in set
Sort_merge_passes表示filesort
执行过的文件分块合并次数的总和,如果该值比较大,建议增大sort_buffer_size
的值。
mysql> show global status like '%sort%';
+-------------------+---------+
| Variable_name | Value |
+-------------------+---------+
| Sort_merge_passes | 226 |
| Sort_range | 0 |
| Sort_rows | 1384911 |
| Sort_scan | 6 |
+-------------------+---------+
4 rows in set
filesort排序方式
filesort
使用的排序方法有两种:
第一种方法是对需要排序的记录生成<sort_key,rowid>
的元数据进行排序,该元数据仅包含排序字段和rowid。排序完成后只有按字段排序的rowid,因此还需要通过rowid进行回表操作获取所需要的列的值,可能会导致大量的随机IO读消耗;
第二种方法是是对需要排序的记录生成<sort_key,additional_fields>
的元数据,该元数据包含排序字段和需要返回的所有列。排序完后不需要回表,但是元数据要比第一种方法长得多,需要更多的空间用于排序。
参数max_length_for_sort_data字段用于控制filesort
使用的排序方法,当所有需要排序记录的字段数量总和小于max_length_for_sort_data
时使用第二种算法,否则会用第一种算法。该值的默认值为1024。
mysql> show global variables like 'max_length_for_sort_data';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| max_length_for_sort_data | 1024 |
+--------------------------+-------+
1 row in set
mysql> set global max_length_for_sort_data = 1024;
Using temporary与Using filesort相关推荐
- Mysql-explain之Using temporary和Using filesort解决方案
Mysql-explain之Using temporary和Using filesort解决方案 参考文章: (1)Mysql-explain之Using temporary和Using fileso ...
- mysql优化-oder by产生的Using temporary与Using filesort问题解决
下面的mysql代码因为order by的原因,出现了Using temporary与Using filesort,优化前代码如下 SELECT DISTINCT( tm.task_no ) task ...
- Mysql(using temporary 与 using filesort)
user(用户表) user_id (PRIMARY KEY) username gender user_device(用户设备表) user_device_id (PRIMARY KEY) ...
- 四、MySql中explain的时候出现Using where; Using index; Using temporary; Using filesort
通过explain查看sql的执行计划时,Extra字段的值往往会看到Using where; Using index; Using temporary; Using filesort 一.using ...
- mysql derived2、Using temporary 和 Using filesort 优化记录
-- 业务每周查询一份报表,每次执行sql磁盘直接由49%涨到%93,执行了几次发现是sql用到了磁盘临时表,对sql进行了改写 -- 原查询sql: SELECTCODE,NAME,num,GROU ...
- mysql using temporary_执行计划中Using filesort,Using temporary相关语句的优化解决_MySQL
bitsCN.com 昨天听开发人员提到,相关的彩票网页当中一个页面刷新的很慢,特别是在提取数据的时候, 今天早上一到,便去找开发人员要去相关的也没进行浏览,窥探哪些数据出现了问题,开发人员 使用PH ...
- 怎么查找执行比较慢的sql语句
一.MySQL数据库有几个配置选项可以帮助我们及时捕获低效SQL语句 1,slow_query_log 这个参数设置为ON,可以捕获执行时间超过一定数值的SQL语句. 2,long_query_tim ...
- MYSQL explain详解[转载]
explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 虽然这篇文章我写的很长,但看起来真的不会困啊,真的都是干货啊!!!! 先解析 ...
- (DBA之路【五】)关于锁的故事
首先很抱歉:这篇文章我其实整合了很多别人的文章,但是因为太多,一开始被没留意出处所以很难声明来源,很抱歉,但是这篇文章只用来作为学习笔记,作为新手,我以后会注意的. (一):什么是锁: 我觉得锁这个东 ...
最新文章
- cocos2dx在eclipse环境下集成ucsdk
- iOS逆向之深入解析如何使用Theos开发插件
- js 正则表达式 取反
- linux100day(day3)--常用文本处理命令和vim文本编辑器
- IPV6 IPV4双栈互通与静态路由
- Win8Metro(C#)数字图像处理--2.7图像伪彩色
- 从源代码安装PostgreSQL10.1
- 手机清除微信内置浏览器缓存
- html如何加入浮动客服,css如何实现客服悬浮效果
- cocos tiledmap无法显示 不显示 无法加载
- 解决Keil4与Keil5在同系统不能共存的问题
- java nio wakeup_Java NIO 的 wakeup 剖析
- 全球与中国飞机内部照明系统市场深度研究分析报告(2021)
- python五大模块_python-5-常用模块
- 开启微信公众号定位服务器,微信公众号的定位是怎样的?
- 数据结构—时间、空间复杂度
- java如何创建枚举类型_Java如何创建枚举类型?
- VMware亮相全球云计算大会
- 【每日早报】2019/10/21
- Altium Designer中如何把贴片元器件放在底层?