zoukankan      html  css  js  c++  java
  • 高性能MySQL-第六章查询性能优化(1)

    通常来说,查询的生命周期大致可以按照顺序来看:从客户端,到服务器,然后在服务器上进行解析,生成执行计划,执行,并返回结果给客户端。

    对于MySQL,最简单的衡量查询开销的三个指标如下:
    响应时间
    扫描的行数
    返回的行数
    查询执行的基础:
    客户端发送一条查询给服务器。
    服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果。否则进入下一阶段。
    服务器端进行SQL解析、预处理,再由优化器生成对应的执行计划。
    MySQL根据优化器生成的执行计划,调用存储引擎的API来执行查询。
    将结果返回给客户端。
    查询状态:
    Sleep:线程正在等待客户端发送新的请求。
    Query:线程正在执行查询或者正在将结果发送给客户端。
    Locked:在MySQL服务器层,该线程正在等待表锁。
    Analyzing and  statistics:线程正在收集存储引擎的统计信息,并生成查询的执行计划。
    Copying to tmp table [on disk]:线程正在执行查询,并且将其结果集都复制到一个临时表中,这种状态一般要么是在做GROUP BY操作,要么是文件排序操作,或者是UNION操作。如果这个状态后面还有“on disk”标记,那表示MySQL正在将一个内存临时表放到磁盘上。
    Sorting result:线程正在对结果集进行排序。
    Sending data:这表示多种情况:线程可能在多个状态之间传送数据,或者在生成结果集,或者在向客户端返回数据。
    MySQL有如下两种排序算法:
    两次传输排序(旧版本使用):
    读取行指针和需要排序的字段,对其进行排序,然后再根据排序结果读取所需要的数据行。
    单次传输排序(新版本使用):
    先读取查询所需要的所有列,然后再根据给定列进行排序,最后直接返回排序结果。
    查询优化器的提示(hint):
    HIGH_PRIORITY和LOW_PRIORITY
    这个提示告诉MySQL,当多个语句同时访问某一个表的时候,哪些语句的优先级相对高些、哪些语句的优先级相对低些。
    HIGH_PRIORITY用于SELECT语句的时候,MySQL会将此SELECT语句重新调度到所有正在等待表锁以便修改数据的语句之前。HIGH_PRIORITY还可以用于INSERT语句,其效果只是简单的抵消了全局LOW_PRIORITY设置对该语句的影响。
    LOW_PRIORITY则正好相反:它会让该语句一直处于等待状态,只要队列中还有需要访问同一个表的语句----即使是那些比该语句还晚提交到服务器的语句。
    这两个提示只对使用表锁的存储引擎有效。
    DELAYED
    这个提示对INSERT和REPLACE有效。MySQL会将使用该提示的语句立即返回给客户端,并将插入的行数据放入到缓冲区,然后在表空闲时批量将数据写入。
    STRAIGHT_JOIN
    这个提示可以放置在SELECT语句的SELECT关键字之后,也可以放置在任何两个关联表的名字之间。第一个用法是让查询中所有的表按照在语句中出现的顺序进行关联。第二个用法则是固定其前后两个表的关联顺序。
    SQL_SMALL_RESULT和SQL_BIG_RESULT
    这两个提示只对SELECT语句有效。它们告诉优化器对GROUP BY或者DISTINCT查询如何使用临时表及排序。SQL_SMALL_RESULT告诉优化器结果集会很小,可以将结果集放在内存中的索引临时表,以避免排序操作。如果是SQL_BIG_RESULT,则告诉优化器结果集可能会非常大,建议使用磁盘临时表做排序操作。
    SQL_BUFFER_RESULT
    这个提示告诉优化器将查询结果放入到一个临时表,然后尽可能快的释放表锁。
    SQL_CACHE和SQL_NO_CACHE
    这个提示告诉MySQL这个结果集是否应该缓存在查询缓存中。
    SQL_CALC_FOUND_ROWS
    它会让MySQL返回的结果集包含更多的信息。查询中加上该提示MySQL会计算除去LIMIT子句后这个查询要返回的结果集的总数,而实际上只返回LIMIT要求的结果集。可以通过函数FOUND_ROW()获得这个值。
    FOR UPDATE和LOCK IN SHARE MODE
    这两个提示主要控制SELECT语句的锁机制,但只对实现了行级锁的存储引擎有效。使用该提示会对符合查询条件的数据行加锁。
    USE INDEX、IGNORE INDEX和FORCE INDEX
    这几个提示会告诉优化器使用或者不使用哪些索引来查询记录。
    在MySQL5.0和更新版本中,新增了一些参数用来控制优化器的行为:
    optimizer_search_depth
    这个参数控制优化器在穷举执行计划时的限度。
    optimizer_prune_level
    该参数默认是打开的,这让优化器会根据需要扫描的行数来决定是否跳过某些执行计划。
    optimizer_switch
    这个变量包含了一些开启/关闭优化器特性的标志位。
  • 相关阅读:
    Anaconda设置虚拟环境并打包exe
    [转]Anaconda, conda, pyenv, virtualenv的区别
    [闲记]2020-2-13
    集合笔记
    Python_列表(list)
    LeetCode 1711. 大餐计数 做题小结
    LeetCode 242. 有效的字母异位词 做题小结
    GitHub Actions教程 使用selenium自动化
    LeetCode 5641. 卡车上的最大单元数 做题小结
    git 批量删除文件夹和文件
  • 原文地址:https://www.cnblogs.com/zhishuiyushi/p/12444482.html
Copyright © 2011-2022 走看看