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. Gmail邮件功能那么强大,GMail被封,在国内怎么用gmail收邮件?

    IT圈子里最热门的话题一定是:gmail被封,该怎么办?gmail由于强大的邮件功能,ITer一定是人手一个or多个,之前想要收发gmail使用imap或SMTP方式是可以在国内正常使用的,目前ima ...

  2. Java做acm所需要的基础知识之排序问题

    Java做acm所需要的基础知识. 以前做acm的题都是用C/C++来写代码的,在学习完Java之后突然感觉Java中的方法比C/C++丰富很多,所以就整理一下平时做题需要用到的Java基础知识. 1 ...

  3. C++[类设计] ini配置文件读写类config

      //in Config.h #pragma once #include <windows.h> #include <shlwapi.h> #pragma comment(l ...

  4. 第一篇!in和exists性能比较和使用

    首先,先看下in和exists的区别: in 是把外表和内表作hash 连接: exists是对外表作loop循环,每次loop循环再对内表进行查询. 普遍的观点是exists比in效率高的.但是这不 ...

  5. 计算方法(二)用C#实现数值积分

    在工程中,经常会遇到积分问题,这时原函数往往都是找不到的,因此就需要用计算方法的数值积分来求. public class Integral { /// <summary> /// 梯形公式 ...

  6. Android中ListView的优化

    第一种方法 重用了convertView,很大程度上的减少了内存的消耗.通过判断convertView是否为null,是的话就需要产生一个视图出来,然后给这个视图数据,最后将这个视图返回给底层,呈献给 ...

  7. 小学生之Oracle分析函数

    分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计值. 分析函数和聚合函数的不同 ...

  8. html跳转到同一个页面的不同位置

    <html> <body> <p><a href="#C4">查看 Chapter 4.</a></p> & ...

  9. java transient关键字和transaction的区别

    transient:表示临时的,不会被持久化,保存进数据库 transaction:表示事务 <div style="background: #fff; color: #0ff;&qu ...

  10. 看android的书的体会

    android书上面的代码有时候有问题,可以在网上搜索这些功能.网上和官方文档里面有很好的说明和例子.