• 8.2.1.19 Optimizing LIMIT Queries 优化LIMIT 查询:


    8.2.1.19 Optimizing LIMIT Queries 优化LIMIT 查询:

    如果你只需要记录的特定列从一个结果集,使用一个LIMIT 子句在一个查询里,

    而不是获取整个结果集,扔掉额外的数据。

    MySQL 有时候优化一个查询有一个LIMIT row_count 子句,没有HAVING 子句:

    如果你只选择一小部分的记录使用LIMIT,MySQL 使用indexed 在一些例子里,

    通常它宁愿选择做一个全表扫描:

    如果你结合LIMIT row_count 和ORDER BY,MySQL 结束排序在它发现第一个row_count ,

    而不是整个结果 。如果排序是通过使用一个索引,这是很快的。

    如果一个filesort 必须被做, 所有匹配查询的记录没有LIMIT 子句是被选择的,

    大多数或者全部被存储, 在row_count 被找到前。

    在初始的记录被找到后,MySQL 不排序任何剩余的结果集。

    这种行为的一种表现是ORDER BY 查询使用和不使用LIMIT 可能返回记录按不同的顺序

    在后面的章节描述:

    如果你组合LIMIT row_count 使用DISTINCT, MySQL 只要找到row_count unique 记录就停止。

    在一些例子中,一个GROUP BY 可以通过读取index 来解决按顺序(或者在索引上做一个排序)

    然后计算汇总直到Index value 改变。在这种情况下,LIMIT row_count 不计算任何不需要GROUP BY 的值

    当MySQL 已经发送 需要的记录给客户端, 它终止查询除非你使用SQL_CALC_FOUND_ROWS.

    行数然后检索用SELECT FOUND_ROWS().

    LIMIT 0 快速的返回一个空的结果集, 这个可以用于检查一个查询的正确性。

    它也可以被用来获得结果列的类型 如果你使用一个MySQL API,

    使结果集数据可用。 与mysql 客户端程序, 你可以使用–column-type-info 选项来显示结果列类型。

    如果server 使用临时表来解决查询,它使用LIMIT row_count 子句来计算需要的空间。

    如果多行具有相同的值在ORDER BY 列里, server 可以自由的返回继续以任何的排序,

    并根据总体的执行计划来进行不同的方式,换句话说,这些行的排序顺序是不确定的。

    一个因素影响执行计划是LIMIT, 因为一个ORDER BY 查询 有和没有LIMIT 可能返回不同顺序的记录。

    考虑这个查询, 是按类型列排序,但是不确定是相对于ID和rating列。

    mysql> SELECT * FROM ratings ORDER BY category;
    +—-+———-+——–+
    | id | category | rating |
    +—-+———-+——–+
    | 1 | 1 | 4.5 |
    | 5 | 1 | 3.2 |
    | 3 | 2 | 3.7 |
    | 4 | 2 | 3.5 |
    | 6 | 2 | 3.5 |
    | 2 | 3 | 5.0 |
    | 7 | 3 | 2.7 |
    +—-+———-+——–+

    包括LIMIT 可能影响每一类值的记录的顺序,例如, 这是一个正确的查询结果:

    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +—-+———-+——–+
    | id | category | rating |
    +—-+———-+——–+
    | 1 | 1 | 4.5 |
    | 5 | 1 | 3.2 |
    | 4 | 2 | 3.5 |
    | 3 | 2 | 3.7 |
    | 6 | 2 | 3.5 |
    +—-+———-+——–+

    在每一种情况下, 记录按ORDER BY 列排序, 这是SQL标准需要的:

    如果它是重要的 确认相同的记录有和没有LIMIT,包括额外的列 在ORDER BY 子句来确定顺序。

    比如,如果id 值是唯一的:

    mysql> SELECT * FROM ratings ORDER BY category, id;
    +—-+———-+——–+
    | id | category | rating |
    +—-+———-+——–+
    | 1 | 1 | 4.5 |
    | 5 | 1 | 3.2 |
    | 3 | 2 | 3.7 |
    | 4 | 2 | 3.5 |
    | 6 | 2 | 3.5 |
    | 2 | 3 | 5.0 |
    | 7 | 3 | 2.7 |
    +—-+———-+——–+

    mysql> SELECT * FROM ratings ORDER BY category, id LIMIT 5;
    +—-+———-+——–+
    | id | category | rating |
    +—-+———-+——–+
    | 1 | 1 | 4.5 |
    | 5 | 1 | 3.2 |
    | 3 | 2 | 3.7 |
    | 4 | 2 | 3.5 |
    | 6 | 2 | 3.5 |
    +—-+———-+——–+

    在MySQL 5.6.2, 优化器会更有效的处理查询(子查询)如下:

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

    这种类型的查询是常见的,显示少数行从一个大的结果集:

    SELECT col1, … FROM t1 … ORDER BY name LIMIT 10;
    SELECT col1, … FROM t1 … ORDER BY RAND() LIMIT 15;

    sort buffer 有一个sort_buffer_size参数,如果sort 原理用于N条记录是足够小的 放入sort buffer

    (M+N 记录如果M被指定), server 可以避免使用一个合并文件,执行整个排序在内存里

    通过处理sort buffer 作为优化队列

  • 相关阅读:
    Android状态栏白底黑字,只需两步轻松搞定
    MyBatis注解
    MyBatis延迟加载和缓存
    MyBatis关联查询
    mybatis智能标签1
    Mybatis智能标签
    增删改查
    初始MyBatis
    第7章:Servlet 基础
    第3章 JSP数据交互(二)
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13351276.html
Copyright © 2020-2023  润新知