MySQL查询优化器--非SPJ优化--LIMIT优化

MySQL支持对不带HAVING子句的LIMIT进行优化,主要的优化点包括:

LIMIT对单表扫描的影响:如果索引扫描可用且花费低于全表扫描,则用索引扫描实现LIMIT(LIMIT取很少量的行,否则优化器更倾向于使用全表扫描)。

LIMIT对排序的影响:如果LIMIT和ORDERBY子句协同使用,当取到LIMIT设定个数的有序元组数后,后续的排序操作将不再进行。

LIMIT对去重的影响:如果LIMIT和DISTINCT子句协同使用,当取到LIMIT设定个数的唯一的元组数后,后续的去重操作将不再进行。

LIMIT受分组的影响:如果LIMIT和GROUPBY子句协同使用,GROUPBY按索引有序计算每个组的总数的过程中,LIMIT操作不必计数直到下一个分组开始计算。

LIMIT 0:直接返回空结果集。


另外,如果是单表排序加LIMIT操作的格式如下:

SELECT ... FROM single_table ... ORDER BY non_index_column [DESC] LIMIT [M,]N;

从SQL语法格式中可以看到,LIMIT子句可以有M和N两个参数,这两个参数影响着排序算法,如下从通常的排序算法先介绍没有LIMIT子句时的排序处理过程,接着对存在LIMIT子句时排序算法受到影响后的变化内容进行介绍,以明确LIMIT操作对排序的影响(注意对两者进行对比以掌握LIMIT对排序的影响)。


LIMIT对排序算法的影响如下:

通常排序算法:


扫描表,重复如下步骤直到文件结束(可能生成多个待归并文件)。


把扫描的元组放入排序的缓存(由参数sort_buffer_size设定)直到缓存填满。


把排序缓存中的前N行(如果指定M,则是M+N行)写入一个“待归并文件”。


对归并文件排序。


按序返回所有文件(归并所有文件)的前N行(如果指定M,则跳过M行再取N行)。



受LIMIT操作影响改进的算法:(适用于N/M+N行待排序的元素小于排序缓存)


扫描表,把每一个满足条件的元组插入到一个按排序有序的队列。


如果队列满,则淘汰最后一个再插入新的。


返回前N行(如果指定M,则跳过M行再取N行)。


你可能感兴趣的:(影响,协同)