说说explain中的Usingfilesort
有时查看SQL的执行计划时, 会遇到Using filesort, 如下.
我们提供的服务有:成都网站建设、网站制作、微信公众号开发、网站优化、网站认证、鄂温克ssl等。为成百上千企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的鄂温克网站制作公司
MySQL> explain select * from tb1 where col1 = 4 order by col2\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tb1
type: ref
possible_keys: idx_col1
key: idx_col1
key_len: 4
ref: const
rows: 1
Extra: Using where; Using filesort
1 row in set (0.00 sec)
这个filesort是说, MySQL要多做一次额外的排序, 确切的说是快速排序(Quicksort).
先初步了解下Quicksort排序的概念(From Wikipedia).
Quicksort is a divide and conquer algorithm. Quicksort first divides a large array into two smaller sub-arrays: the low elements and the high elements. Quicksort can then recursively sort the sub-arrays.
The steps are:
1. Pick an element, called a pivot, from the array.
2. Partitioning: reorder the array so that all elements with values less than the pivot come before the pivot, while all elements with values greater than the pivot come after it (equal values can go either way). After this partitioning, the pivot is in its final position. This is called the partition operation.
3. Recursively apply the above steps to the sub-array of elements with smaller values and separately to the sub-array of elements with greater values.
再看下Python对于其的一个实现.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
def quicksort(array):
if len(array) < 2:
return array
else:
pivot = array[0]
less = [i for i in array[1:] if i <= pivot]
greater = [i for i in array[1:] if i > pivot]
return quicksort(less) + [pivot] + quicksort(greater)
print(quicksort([10, 5, 2, 3]))
再回来说filesort, 在MySQL中有the Original, Modified和In-Memory filesort Algorithm 3种实现.
The Original filesort Algorithm
1. 扫描或根据WHERE条件, 获取所有记录.
2. 把每条记录的sort key和row ID, 即
3. 进行若干次multi-merge操作, 将所有row ID写入结果文件.
4. 根据row ID再次获取记录.
很容易发现, 上面的步骤1和4, 一共读取了2遍记录, 所以也就有了下面的改进实现.
The Modified filesort Algorithm
较Original改变的地方是, 在第2步记录的是sort key和涉及到的其它列, 即
这个算法中
The In-Memory filesort Algorithm
那么排序数据量比较小的情况下呢, 小到在sort buffer中就可完成排序, 针对这种情况又有了In-Memory filesort. 这时MySQL把sort buffer当成priority queue使用, 避免使用临时文件.
上面可以看到MySQL已在尽量优化排序了, 也从侧面说明其不希望排序的出现, 如最开始的SQL, 建立一个(col1, col2)的联合索引, 就可以避免排序了, 该原因还要从B+树索引说起...
若感兴趣可关注订阅号”数据库最佳实践”(DBBestPractice).
网站栏目:说说explain中的Usingfilesort
URL网址:http://myzitong.com/article/pdpjsi.html