博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MySQL如何优化ORDER BY
阅读量:7021 次
发布时间:2019-06-28

本文共 2043 字,大约阅读时间需要 6 分钟。

hot3.png

在某些情况中,MySQL可以使用一个索引来满足ORDER BY子句,而不需要额外的排序。

即使ORDER BY不确切匹配索引,只要WHERE子句中的所有未使用的索引部分和所有额外的ORDER BY 列为常数,就可以使用索引。下面的查询使用索引来解决ORDER BY部分:

注:key_part1,key_part2为建立了索引的列

SELECT * FROM t1

    ORDER BY key_part1,key_part2,... ;

   

SELECT * FROM t1

    WHERE key_part1=constant

    ORDER BY key_part2;

   

SELECT * FROM t1

    ORDER BY key_part1 DESC, key_part2 DESC;

   

SELECT * FROM t1

    WHERE key_part1=1

    ORDER BY key_part1 DESC, key_part2 DESC;

在某些情况下,MySQL不能使用索引来解决ORDER BY,尽管它仍然使用索引来找到匹配WHERE子句的行。这些情况包括:

·         对不同的关键字使用ORDER BY

·                SELECT * FROM t1 ORDER BY key1, key2;

·         对关键字的非连续元素使用ORDER BY

·                SELECT * FROM t1 WHERE key2=constant ORDER BY key_part2;

·         混合ASCDESC

·                SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;

·         用于查询行的关键字与ORDER BY中所使用的不相同:

·                SELECT * FROM t1 WHERE key2=constant ORDER BY key1;

·         你正联接许多表,并且ORDER BY中的列并不是全部来自第1个用于搜索行的非常量表。(这是EXPLAIN输出中的没有const联接类型的第1个表)

·         有不同的ORDER BYGROUP BY表达式。

·         使用的表索引的类型不能按顺序保存行。例如,对于HEAP表的HASH索引情况即如此。

通过EXPLAIN SELECT ...ORDER BY,可以检查MySQL是否可以使用索引来解决查询。如果Extra列内有Using filesort,则不能解决查询。参见。

文件排序优化不仅用于记录排序关键字和行的位置,并且还记录查询需要的列。这样可以避免两次读取行。文件排序算法的工作象这样:

1.    读行匹配WHERE子句的行,如前面所示。

2.    对于每个行,记录构成排序关键字和行位置的一系列值,并且记录查询需要的列。

3.    根据排序关键字排序元组

4.    按排序的顺序检索行,但直接从排序的元组读取需要的列,而不是再一次访问表。

该算法比以前版本的Mysql有很大的改进。

为了避免速度变慢,该优化只用于排序元组中的extra列的总大小不超过max_length_for_sort_data系统变量值的时候。(将该变量设置得太高的的迹象是将看到硬盘活动太频繁而CPU活动较低)

如果想要增加ORDER BY的速度,首先看是否可以让MySQL使用索引而不是额外的排序阶段。如果不能,可以尝试下面的策略:

·         增加sort_buffer_size变量的大小。

·         增加read_rnd_buffer_size变量的大小。

·         更改tmpdir指向具有大量空闲空间的专用文件系统。该选项接受几个使用round-robin(循环)模式的路径。在Unix中路径应用冒号(:)区间开,在WindowsNetWareOS/2中用分号()。可以使用该特性将负载均分到几个目录中。注释:路径应为位于不同物理硬盘上的文件系统的目录,而不是同一硬盘的不同的分区。

默认情况下,MySQL排序所有GROUP BY col1col2...查询的方法如同在查询中指定ORDER BY col1col2...。如果显式包括一个包含相同的列的ORDER BY子句,MySQL可以毫不减速地对它进行优化,尽管仍然进行排序。如果查询包括GROUP BY但你想要避免排序结果的消耗,你可以指定ORDER BY NULL禁止排序。例如:

INSERT INTO foo

SELECT a, COUNT(*) FROM bar GROUP BY a ORDER BY NULL;

转载于:https://my.oschina.net/ydsakyclguozi/blog/193435

你可能感兴趣的文章
javascript之this指向
查看>>
FTP实时更新上传脚本
查看>>
awk中多个分隔符^识别办法
查看>>
Centos7 初始化MySQL5.7数据库
查看>>
从零开始的linux 第十八章
查看>>
c#获取逻辑硬盘信息
查看>>
vSphere虚拟化之vClient安装虚拟机
查看>>
23种设计模式介绍(二)---- 结构型模式
查看>>
IOT物联网观察之商业本质是价值交换,物量经济交换逻辑是什么?
查看>>
MySQL8.0 新特性:Partial Update of LOB Column
查看>>
计算机网络数据链路层
查看>>
Python库的使用
查看>>
云上自动化:全球云上自动化编排系统比拼
查看>>
解读AI行业发展趋势
查看>>
嵌入式开发培训都要学什么?零基础参加嵌入式学习培训能学会吗
查看>>
flume的初体验
查看>>
hbase的基本操作
查看>>
DevOps工程师到底做些什么?
查看>>
解析RDD在Spark中的地位
查看>>
高质量SEO文章编辑规范技巧之:格式
查看>>