using filesort

一般人的回答是: “当行数据太大,导致内存无法容下这些数据产生的临时表时,他们就会被放入磁盘中排序。”  很不幸,这个答案是错的 ,临时表在太大的时候确实会到磁盘离去,但是EXPLAIN不会显示这些。

The truth is, filesort is badly named. Anytime a sort can’t be performed from an index, it’s a filesort. It has nothing to do with files. Filesort should be called “sort.” It is quicksort at heart.

那么事实是, filesort 这个名字取得太搓逼了。 filesort的意思是只要一个排序无法使用索引来排序,就叫filesort。他和file没半毛钱关系。filesort应该叫做sort。(笔者补充一下:意思是说如果无法用已有index来排序,那么就需要数据库服务器额外的进行数据排序,这样其实是会增加性能开销的。)

另外不光order by会出现filesort  group by没有使用索引一样会出现

检查sort状态

show session status like '%sort%';

sort_merge_passes  由于sort buffer不够大,不得不将需要排序的数据进行分段,然后再通过sort merge的算法完成整个过程的merge总次数,一般整个参数用来参考sort buffer size 是否足够。

sort range session/global级别(单位:次) 通过range scan完成的排序总次数。

sort rows   session/global 级别(单位:row) 排序的总行数。

sort scan   通过扫描表完成的排序总次数。

当无法避免排序操作时,又该如何来优化呢?很显然,应该尽可能让 MySQL 选择使用第二种单路算法来进行排序。这样可以减少大量的随机IO操作,很大幅度地提高排序工作的效率。

1. 合理设置索引 让排序字段使用上索引排序

2. 加大 max_length_for_sort_data 参数的设置

3. 去掉不必要的返回字段

当内存不是很充裕时,不能简单地通过强行加大上面的参数来强迫 MySQL 去使用改进版的排序算法,否则可能会造成 MySQL 不得不将数据分成很多段,然后进行排序,这样可能会得不偿失。此时就须要去掉不必要的返回字段,让返回结果长度适应 max_length_for_sort_data 参数的限制。

4. 增大 sort_buffer_size 参数设置

增大 sort_buffer_size 并不是为了让 MySQL选择改进版的排序算法,而是为了让MySQL尽量减少在排序过程中对须要排序的数据进行分段,因为分段会造成 MySQL 不得不使用临时表来进行交换排序。

Using temporary

内部临时表产生的时机有以下几种:

  • 使用 ORDER BY 子句和一个不一样的 GROUP BY 子句(经过笔者实验,应该是GROUP BY一个无索引列,就会产生临时表),或者 ORDER BY 或 GROUP BY 的列不是来自JOIN语句序列的第一个表,就会产生临时表(经笔者实验,应该是使用JOIN时, GROUP BY 任何列都会产生临时表)
  • DISTINCT 和 ORDER BY 一起使用时可能需要临时表(笔者实验是只要用了DISTINCT(非索引列),都会产生临时表)
  • 用了 SQL_SMALL_RESULT, mysql就会用内存临时表。定义:SQL_BIG_RESULT or SQL_SMALL_RESULT can be used with GROUP BY or DISTINCT to tell the optimizer that the result set has many rows or is small, respectively. For SQL_BIG_RESULT, MySQL

有些情况服务器会直接使用磁盘临时表

  • 表里存在BLOB或者TEXT的时候(这是因为MEMORY引擎不支持这两种数据类型,这里笔者补充一下,并非只要查询里含有BLOB和TEXT类型的列就会产生磁盘临时表,按照高性能MYSQL里的话,应该这么说:“Because the Memory storage engine doesn't support the BLOB and TEXT types, queries that use BLOB or TEXT columns and need an implicit temporary table will have to use on-disk MyISAM temporry tables, even for only a few rows.”也就是说如果我们的查询中包含了BLOB和TEXT的列,而且又需要临时表,这时候临时表就被强制转成使用磁盘临时表,所以此书一直在提醒我们,如果要对BLOB和TEXT排序,应该使用SUBSTRING(column, length)将这些列截断变成字符串,这样就可以使用in-memory临时表了
  • GROUP BY 或者 DISTINCT 子句大小超过 512 Bytes
  • 使用了UNION 或 UNION ALL 并且 SELECT 的列里有超过512 Bytes的列

如果内置内存临时表创建后变得太大,MySQL会自动将它转换成磁盘临时表。内存临时表的大小取决与 tmp_table_size参数和max_heap_table_size参数的值。用 CREATE TABLE 产生的内存临时表的大小取决与 max_heap_table_size来决定是否要将其转换成磁盘临时表

当服务器生成一个内存临时表,Created_tmp_tables状态变量值会增加,当服务器创建了一个磁盘临时表时,Created_tmp_disk_tables状态变量值会增加。(这几个变量可以通过 show status命令查看得到)

Tips: internal temporaray table 的大小受限制的是tmp_table_size和max_heap_table_size的最小值;而 user-created temporary table的大小只受限与max_heap_table_size,而与tmp_table_size无关

mysql using filesort Using temporary的更多相关文章

  1. Why does MySQL produce so many temporary MYD files?

    http://dba.stackexchange.com/questions/30505/why-does-mysql-produce-so-many-temporary-myd-files Data ...

  2. 一次mysql 优化 (Using temporary ; Using filesort)

    遇到一个SQL执行很慢 SQL 如下: SELECT ... FROM tableA WHERE time >= 1492044535 and time <= 1492046335 GRO ...

  3. 执行计划中Using filesort,Using temporary相关语句的优化解决

    昨天听开发人员提到,相关的彩票网页当中一个页面刷新的很慢,特别是在提取数据的时候,今天早上一到,便去找开发人员要去相关的也没进行浏览,窥探哪些数据出现了问题,开发人员使用PHP开发,所以我用IE很容易 ...

  4. 【MySQL】filesort.cc 源代码阅读笔记

    最近阅读了部分MySQL排序的代码,把心得记录一下. 参考代码 MySQL: 文件: filesort.cc 函数: filesort() 排序过程伪代码 function filesort(tabl ...

  5. mysql Using filesort 索引不可用问题

        今天上班发现线上机器CPU告警,看了一下发现是mysqld一直占用CPU处于满负荷状态,show processlist;一下,发现很多查询在排序状态,随便拿了一条sql explain看了一 ...

  6. MySQL优化:explain using temporary

    什么时候会使用临时表:group/order没设计好的时候 1.order没用索引 2.order用了索引, 但不是和where相同的索引 3.order用了两个索引, 但不是联合索引 4.order ...

  7. MySQL调优 —— Using temporary

      DBA发来一个线上慢查询问题. SQL例如以下(为突出重点省略部分内容): select distinct article0_.id, 等字段 from article_table article ...

  8. mysql之filesort原理

    在执行计划中,可能经常看到有Extra列有filesort,这就是使用了文件排序,这当然是不好的,应该优化,但是,了解一下他排序的原理也许很有帮助,下面看一下filesort的过程: 1.根据表的索引 ...

  9. Mysql EXPLAIN 相关疑问: Using temporary ; Using filesort

    一.什么是Using temporary ; Using filesort 1. using filesort filesort主要用于查询数据结果集的排序操作,首先MySQL会使用sort_buff ...

随机推荐

  1. 文件是数据(字节)流的抽象-为什么C++中会把文件操作抽象为fstream?

    这不过是返祖罢了.正确的问题是为什么会把数据流抽象成文件. 设备-字节流-文件. 一切皆为文件,所有不同种类的类型都被抽象成文件(比如:块设备,socket套接字,pipe队列). 文件抽象为数据流一 ...

  2. 视图 b

  3. 如何清理Macbook垃圾文件

    如何清理Macbook垃圾文件,腾出更多硬盘空间 在Macbook使用久之后,会发现本来还富裕的硬盘,变得越来越少,尤其现在Macbook使用容量很小的固态硬盘.在此种情况下,该如何清理Macbook ...

  4. 用Java编写银行存钱取钱

    const readline = require('readline-sync')//引用readline-sync let s = 2;//错误的次数 for (let i = 0; i < ...

  5. ajax 与 axios区别

    Ajax: Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术. Ajax = 异步 J ...

  6. SHELL脚本简单的赋值与递增

    Count=`expr $Count + 1`;#可以在各种shell执行,其他类C的写法只能在指定的bash版本执行; 赋值不能带$, 带$相当于字符串常量了;执行脚本参考如下 #!/bin/sh ...

  7. windows10上安装mysql

    环境:windwos 10(1511) 64bit.mysql 5.7.14 一.下载mysql 1. 在浏览器里打开mysql的官网http://www.mysql.com/ 2. 进入页面顶部的& ...

  8. 缓存反向代理-Varnish

    简介 Varnish是一款高性能.开源的缓存反向代理服务器.它从客户端接受请求,并尝试从缓存中响应请求,如果无法从缓存中提供响应,Varnish 向后端服务器发起请求,获取响应,将响应存储在缓存中,然 ...

  9. vue的实例

    vue的实例 创建一个vue实例的写法和创建一个变量一样 var vm = new Vue{{ //我们一般用vm来接收vue的实例,vm是 ViewModel的缩写 }} 然后,我们就可以给vue实 ...

  10. 【sql server常用操作{增删改查}】

    use DB_x   go   drop database DB_y   create database DB_y --创建数据库   on primary --指定主数据文件   (   name= ...