8.2.1.15 ORDER BY Optimization  ORDER BY 优化

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

index 可以用于即使ORDER BY 不精确的匹配index,

只要所有未使用的索引的部分和所有额外的ORDER BY 列是WHERE 子句中的常量。

下面的查询使用index来解决ORDER BY 部分:

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; SELECT * FROM t1
WHERE key_part1 > constant
ORDER BY key_part1 ASC; SELECT * FROM t1
WHERE key_part1 < constant
ORDER BY key_part1 DESC; SELECT * FROM t1
WHERE key_part1 = constant1 AND key_part2 > constant2
ORDER BY key_part2; 在一些情况下, MySQL 不能使用indexes来解决ORDER BY,尽管它仍旧使用索引来找到匹配的记录。 例如如下: 1. 查看使用ORDER BY 在不同的索引上: SELECT * FROM t1 ORDER BY key1, key2; 2.查询使用ORDER BY 在一个索引非连续的部分 SELECT * FROM t1 WHERE key2=constant ORDER BY key_part2; 3.查询混合ASC和DESC SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC; 4.index 用于获取记录不同于一个用于ORDER BY SELECT * FROM t1 WHERE key2=constant ORDER BY key1; 5.查询使用ORDER BY 使用一个表达式 包含条件除index列以外 SELECT * FROM t1 ORDER BY ABS(key);
SELECT * FROM t1 ORDER BY -key; 6.查询关联很多表, 列在ORDER BY 不是所有从第一个非常量表来检索记录 7.查询有不同的ORDER BY 和GROUP BY 表达式 8. 有一个索引只有前缀列命名在ORDER BY 子句,在这种情况下, index 不能被完全使用来解决排序顺序。 如果 如果 只有一个CHAR(20) 的前10个字节被索引, 一个索引的可利用性对于排序可能是有影响的通过使用列的别名,假设 列t1.a是索引的。 在这种情况下, 列的名字在选择的list 是a.it 它指向t1.a 索引可以被使用 SELECT a FROM t1 ORDER BY a; 在这个语句, 列的名字在select list 是a, 但是它是alias的名字。它指向ABS(a), 因此指向a 在ORDER BY,索引不能被使用 SELECT ABS(a) AS a FROM t1 ORDER BY a; 在下面的语句,ORDER BY 指向一个名字 不是列的名字在SELECT 列表。 但是有一个列在t1叫做a,因此 ORDER BY 使用 索引可以被使用(排序顺序可能是不同的) SELECT ABS(a) AS b FROM t1 ORDER BY a; 默认, MYSQL 排序所有的GROUP BY col1,col2 查询如果你指定ORDER BY col1,col2, 如果你包含一个显示的ORDER BY 子句 包含相同的列集合 注意: 如果一个查询包含 GROUP BY 但是你需要避免 排序结果的开销,你可以指定排序通过ORDER BY NULL INSERT INTO foo
SELECT a, COUNT(*) FROM bar GROUP BY a ORDER BY NULL; 使用EXPLAIN SELECT ... ORDER BY,你可以检查是否 MySQL 使用索引来查询。 它不能?你使用filesort 在额外的列 mysql> explain select * from Client order by sn
-> ;
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------+
| 1 | SIMPLE | Client | index | NULL | PRIMARY | 4 | NULL | 5884 | NULL |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------+
1 row in set (0.03 sec) mysql> explain select * from Client order by status;
+----+-------------+--------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | Client | ALL | NULL | NULL | NULL | NULL | 5884 | Using filesort |
+----+-------------+--------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec) MySQL 有2种 filesort 算法用于排序和检索记录。 原始方法只使用ORDER BY 列, 修改方法不只是使用ORDER BY 列, 而是查询涉及的所有列 优化器选择文件排序算法使用,它通常使用修改算法除了当BLOB或者TEXT 列被设计, 在这种情况下它会使用原始的算法。对于两种算法, sort buffer size 是sort_buffer_size 系统变量控制的 [root@zjzc01 binlog]# cat /etc/my.cnf | grep sort
sort_buffer_size=1M 原始的filesort 算法如下: 1. 读取所有的记录根据索引或者通过表扫描,跳过不匹配的记录 2. 对于每条记录, 存储在sort buffer 一个元组有一对值组成(sort key 值和row ID) 3.如果所有的pairs 到放到sort buffer, 不需要创建临时文件。否则, 当sort buffer 变满时, 运行一个qsort(quicksort) 在内存里 写到一个临时文件,保存一个指向排序后的块 4.重复前面的步骤, 知道所有行被读取 5.做一个 合并到 MERGEBUFF (7) 区域到一个block在另外的temporary 文件。 重复知道所有的blocks 从第一个文件是在第2个文件 6.重复下面知道有较少相比 MERGEBUFF2 (15)块留下 7. 在最后的合并,只有row ID (值对的最后部分)是写入到结果文件 8. 读按顺序存储的记录使用row IDs 在结果文件。 优化这个, 读取row IDs的大的块,排序它们,使用它们读取排序的记录到row buffer. row buffer size 是 read_rnd_buffer_size 系统变量设置 一个问题是它会读取量词, 一次在where 条件评估时, 另外一次在排序值对后。 修改的filesort 算法采用一个优化的来避免读2次, 它记录仪sort key 值,代替row ID 它记录查询涉及的列, 修改后的文件排序算法工作如下: 1.读取匹配WHERE 子句的记录 2.对于每个行, 存储在sort buffer 一个元组 有sort key值和查询涉及的列组成 3.当排序区变满后, sort 元组通过sort key 值在内存里写到一个临时文件 mysql> show variables like '%sort%';
+--------------------------------+---------------------+
| Variable_name | Value |
+--------------------------------+---------------------+
| innodb_disable_sort_file_cache | OFF |
| innodb_ft_sort_pll_degree | 2 |
| innodb_sort_buffer_size | 1048576 |
| max_length_for_sort_data | 1024 |
| max_sort_length | 1024 |
| myisam_max_sort_file_size | 9223372036853727232 |
| myisam_sort_buffer_size | 8388608 |
| sort_buffer_size | 1048576 |
+--------------------------------+---------------------+
8 rows in set (0.00 sec)

8.2.1.15 ORDER BY Optimization ORDER BY 优化的更多相关文章

  1. MYSQL ORDER BY Optimization

    ORDER BY Optimization 某些情况下,MYSQL可以使用index排序而避免额外的sorting. 即使order by语句列不能准确的匹配index,只要没有index中(不在or ...

  2. 8.2.1.4 Index Merge Optimization 索引合并优化:

    8.2.1.4 Index Merge Optimization 索引合并优化: 索引合并方法是用于检索记录 使用多个 范围扫描和合并它们的结果集到一起 mysql> show index fr ...

  3. MySQL高级 之 order by、group by 优化

    参考:  https://blog.csdn.net/wuseyukui/article/details/72627667 order by示例 示例数据: Case 1 Case 2 Case 3 ...

  4. OPEN A PO ORDER OR SO ORDER

    OPEN PO ORDER fnd_function.Execute(Function_Name => 'PO_POXPOEPO', Open_Flag => 'Y', Session_F ...

  5. SQL sqlserver order by 1,order by 后面直接加数字,多个字段排序

    ①select * from table order by n 表示select里面的第n个字段 ②多个字段排序

  6. linux下order by 报出ORDER BY clause is not in SELECT list

    一.问题: 在程序执行查询的时候,order by 不能找到要排序的列 二.解决: 在linux环境下,程序之前连接其他库可以正常运行,但是换了一个库后数据就不能正常的显示了,查看后台报出排序列找不到 ...

  7. Android进阶笔记15:ListView篇之图片优化

    1.图片异步加载: (1)处理图片的方式: 如果ListView中自定义的Item中有涉及到大量图片的,一定要对图片进行细心的处理,因为图片占的内存是 ListView 项中最头疼的,处理图片的方法大 ...

  8. Mysql优化(出自官方文档) - 第四篇

    Mysql优化(出自官方文档) - 第四篇 目录 Mysql优化(出自官方文档) - 第四篇 1 Condition Filtering 2 Constant-Folding Optimization ...

  9. SORT UNIQUE|AGGREGATE|GROUP BY|ORDER BY|JOIN

    相信做oracle开发和管理的朋友对sort肯定不会陌生,大家通常都遇到这样那样的排序性能问题,所以我写这一系列关于sort的文章告诉大家在oracle里面sort是怎么一回事以及如果调整sort获得 ...

随机推荐

  1. angular Error: [ng:areq]

    在使用augularjs的时候,爆了个错误: 后来经过对比,原来是我的<html>标签多了点东西

  2. (转)Maven实战(五)坐标详解

    1.为什么要定义Maven坐标      在我们开发Maven项目的时候,需要为其定义适当的坐标,这是Maven强制要求的.在这个基础上,其他Maven项目才能应用该项目生成的构件. 2.Maven坐 ...

  3. 实战:mysql版本号升级

    /***************************************************** mysql 5.6.19 升级到5.6.21 ********************** ...

  4. poj 2749 Building roads (二分+拆点+2-sat)

    Building roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6229   Accepted: 2093 De ...

  5. boost 相等与等价的区别

  6. C#时间戳的获取与转换方法

    /// <summary> /// 获取当前时间戳 /// </summary> /// <param name="bflag"></pa ...

  7. noip 2009 细胞分裂

    /*数论题 考察唯一分解定理 当然用到一些技巧*/ #include<iostream> #include<cstdio> #include<cstring> #d ...

  8. hdu 2156

    #include <iostream> #include <stdio.h> using namespace std; int main() { int i,n; while( ...

  9. MongoDB与PHP的添加、修改、查询、删除

    链接数据库使用下面的代码创建一个数据库链接 <?php$connection = new Mongo(); //链接到 localhost:27017$connection = new Mong ...

  10. c - 给分数分级别

    /* 题目: 学习成绩>=90 分的同学用 A 表示, 80-89 分之间的用 B 表示,70-79 分的用 C 表示, 60-69 分用 D表示,小于60分用E表示. 分析: 使用swith. ...