zoukankan      html  css  js  c++  java
  • 8.2.1.15 ORDER BY Optimization

    8.2.1.15 ORDER BY Optimization

    在有些情况下,MySQL 可以使用index 来返祖order by 子句而不做任何额外的排序:

    index 可以用于使用,即使 ORDER BY 不匹配index exactly,

    只要所有的索引的不使用的部分和所有的额外的ORDER BY 子句是常量在WHERE 子句里,

    下面的查询使用index 来拒绝排序:

    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 不能使用index 来解决ORDER BY ,尽管 它仍旧使用索引来找到匹配WHERE 条件的记录,

    这种情况如下:

    1.你使用ORDER BY 在不同的keys上

    SELECT * FROM t1 ORDER BY key1, key2;

    2.你使用ORDER BY在一个索引的非连续部分

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

    1. 你混合ASC和DESC

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

    4.索引用于提取记录和用于排序的不一样:

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

    5.SELECT * FROM t1 ORDER BY ABS(key);
    SELECT * FROM t1 ORDER BY -key;

    你关联了很多表, ORDER BY 列 不是从第一个非常量表来用于检索记录

    (这是第一个表在EXPLAIN 输出,没有常量关联类型)

    你有不同的ORDER BY 或者GROUP BY 表达式:

    你的索引只有一个前缀列在ORDER BY子句,在这种情况下, index 不能用于完整的剞劂排序顺序。

    比如,如果你有一个CHAR(20)列, 但是索引只有10个字节,索引不能区分 传递的第10个字节和一个排序需要

    表索引类型使用不能用于按顺序的存储记录,比如, 对于一个HASH index 在一个MEMORY table.

    一个索引用于排序的有效性可能受别名的使用影响。假设column t1.a 是有索引,

    在这个语句里, 在查询列表里 列的名字是a. 它指向t1.a,因此关联到a在ORDER BY ,index 可以被使用:

    SELECT a FROM t1 ORDER BY a;

    在这个语句, SELECT语句里的列仍旧是a, 但是它是alias name.

    但是它是别名,它指向ABS(a), 因此涉及a在ORDER BY ,索引不能被使用:

    SELECT ABS(a) AS a FROM t1 ORDER BY a;

    在下面的语句,ORDER BY 指向一个name,但不是SELECT 列表里的列名。

    但是有一个列在t1 叫做a, 因此ORDER BY 使用这个, 索引被使用

    SELECT ABS(a) AS b FROM t1 ORDER BY a;

    默认情况下, MySQL 排序所有的GROUP BY col1,col2 查询如果你指定col1,col2 在查询里。

    如果你包含一个明确的ORDER BY 子句 包含相同的列,

    MySQL 优化总是没有任何速度害处,尽管排序仍旧发生。如果一个查询包含GROUP BY ,

    但是比需要避免排序结果的开销,你可以阻止排序通过指定ORDER BY NULL。

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

    注意:

    依赖隐含的GROUP BY 排序在MySQL 5.6 是过时的,为了完成一个特定的排序顺序,

    最好是使用一个显示的ORDER 通过子句。GROUP BY 排序是一个MySQL 扩展,可能会在未来的版本中改变。

    例如, 有可能使优化器来排序分区。

    EXPLAIN SELECT … ORDER BY,

    你可以检查是否MySQL 可以使用索引来解决查询,

    它不能如果你看到使用filesort 在额外的列。

    See Section 8.8.1, “Optimizing Queries with EXPLAIN”.

    Filesort 使用一个固定长度行存储格式类似于MEMORY 内存引擎的使用

    MySQL 有2个filesort 算法用于排序和检索结果, 原始的方法是只使用ORDER BY 列。

    修改的方法不只是使用ORDER BY 子句,而是所有涉及查询的列。

    优化器选择 哪个filesort 算法来使用, 它通常使用修改的算法出了当BLOB或者TEXT 列被涉及,

    在这种情况下,利用原来的算法。对于两种算法,sort buffer size 是sort_buffer_size 系统变量控制:

    原始的filesort 算法工作如下:

    1. 读取所有的记录根据索引或者表扫描,跳过不匹配的行:

    2. 对于每一行, 存储一对值(sort key value和row ID)在sort buffer:

    3. 如果所有的对被放入到sort buffer, 没有临时文件产生。否则, 当sort buffer 变满,

    运维一个qsort(quicksort)在内存里,写入到临时文件,保留一个指针指向排序块。

    1. 重复前面的步骤,直到所有的行被读取

    2. 做一个multi-merge 到MERGEBUFF (7) 区域到一个block 在另外的一个临时文件,

    重复直到所有的块从第一个文件都到第2个文件。

    5.重复下面的直到 有很少的相比 MERGEBUFF2 (15) blocks留下

    6.在最后一个 multi-merge, 只有row ID( 最后部分的对值)是写到一个结果文件)

    这种方法的一个问题是它读取行要2次, 一次在WHERE 子句执行时, 另外一个在排序值后。

    即使第一次访问记录成功(比如,一个表扫描是被做)

    第2次是随机访问的(sort keys是有序的,但是记录位置不是)

    修改filesort 算法采用一个优化用于避免读取2次, 它记录sort key value,代替row ID,

    它记录查询相关的列。 修改后的filesort 算法工作如下:

    读取匹配WHERE 条件的记录:

    1.对于每一行, 记录一个值的tuple 有sort key 值组成和查询涉及的列

    1. 当sort buffer 变满, 排序tuples 通过sort key value 在内存里和写到temporary 文件

    3.在 merge-sorting the temporary file, 检索从排序的order里检索数据,

    但是读需要的列直接从存储的tuples 相比第2次访问表

    使用修改后的filesort 算法,tuples 是比原来使用的方法长, 它们中的少数放入到sort buffer.

    其结果是,它是可能的对于额外的I/O 来使修改后的方法更慢,而不是更快。

    为了避免变慢,优化器使用修改算法只有在额外的列的总大小在sort tuple 不超过max_length_for_sort_data 的值。

    如果一个filesort 被执行, EXPLAIN 输出包括 使用filesort in the Extra column.

    优化的trace 输出包括一个filesort_summary block. For example:

    “filesort_summary”: {
    “rows”: 100,
    “examined_rows”: 100,
    “number_of_tmp_files”: 0,
    “sort_buffer_size”: 25192,
    “sort_mode”: “

  • 相关阅读:
    setMasksToBounds
    CSRF跨站
    ORM: object relationship mapping
    orm查询
    图书管理系统(增删改)
    django图书管理半成品(MySQL)
    模板继承(练习测试)
    模板层(template)
    django命令(笔记,自己看的)
    django(注册→登录→主页)增强版
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13351282.html
Copyright © 2011-2022 走看看