zoukankan      html  css  js  c++  java
  • mysql优化:explain 和 profile

    此文转自:https://blog.csdn.net/hanjungua8144/article/details/84317829

    一、SQL查询语句优化基本思路和原则

    优化更需要优化的Query。
    定位优化对象的性能瓶颈。
    明确优化目标。
    从Explain入手。
    多使用Profile。
    永远用小结果集驱动大的结果集。
    尽可能在索引中完成排序。
    只取自己需要的Columns。
    仅仅使用最有效的过滤条件。
    尽可能避免复杂的Join和子查询

    二、从explain入手

    用explain进行分析执行计划,并解释各个值

    id 这个id不是主键的意思,他是用来标识select查询的序列号,包含一组数字,表示查询中执行select子句或者操作表的顺序。会出现以下情况:
    id相同:按从上到下顺序执行。

    id不同:id值越大,优先级越高,越先被执行。

    id相同不同的同时存在:优先执行id值大的,如果id值相同,则按从上到下的顺序执行。

    id为null表示是用来合并结果集的,在sql使用union关键字合并结果集就会出现他。

     

    • select_type

    • type

    访问类型,sql查询优化中一个很重要的指标,结果值从好到坏依次是:

    system>const>eq_ref>ref>fulltext >ref_or_null >index_merge >unique_subquery >index_subquery >range>index>ALL

    system 表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,可以忽略不计。

    const 表示通过索引一次就找到了,const用于比较primary key 或者 unique索引。因为只需匹配一行数据,所有很快。如果将主键置于where列表中,mysql就能将该查询转换为一个const。

    eq_ref 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键 或 唯一索引扫描。

    ref 非唯一性索引扫描,返回匹配某个单独值的所有行。本质是也是一种索引访问,它返回所有匹配某个单独值的行,然而他可能会找到多个符合条件的行,所以它应该属于查找和扫描的混合体。

    range 只检索给定范围的行,使用一个索引来选择行。key列显示使用了那个索引。一般就是在where语句中出现了bettween、<、>、in等的查询。这种索引列上的范围扫描比全索引扫描要好。只需要开始于某个点,结束于另一个点,不用扫描全部索引。

    index Full Index Scan,index与ALL区别为index类型只遍历索引树。这通常为ALL块,应为索引文件通常比数据文件小。(Index与ALL虽然都是读全表,但index是从索引中读取,而ALL是从硬盘读取)。

    ALL Full Table Scan,遍历全表以找到匹配的行。

    • key

    实际使用的索引,如果为NULL,则没有使用索引。

    查询中如果使用了覆盖索引,则该索引仅出现在key列表中

     

    • key_len

    表示索引中使用的字节数,查询中使用的索引的长度(最大可能长度),并非实际使用长度,理论上长度越短越好。key_len是根据表定义计算而得的,不是通过表内检索出的。

    • ref

    显示索引的那一列被使用了,如果可能,是一个常量const。

    • rows

    根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数。

    • Extra

    不适合在其他字段中显示,但是十分重要的额外信息

    1、Using filesort mysql对数据使用一个外部的索引排序,而不是按照表内的索引进行排序读取。也就是说mysql无法利用索引完成的排序操作成为“文件排序”。

    2、Using temporary 使用临时表保存中间结果,也就是说mysql在对查询结果排序时使用了临时表,常见于order by 和 group by。

     

    3、Using index 表示相应的select操作中使用了覆盖索引,避免了访问表的数据行,效率高。如果同时出现Using where,表明索引被用来执行索引键值的查找(参考上图)如果没用同时出现Using where,表明索引用来读取数据而非执行查找动作 。

     

    覆盖索引: 也叫索引覆盖。就是select列表中的字段,只用从索引中就能获取,不必根据索引再次读取数据文件,换句话说查询列要被所建的索引覆盖。

    注意:

    a、如需使用覆盖索引,select列表中的字段只取出需要的列,不要使用select *。

    b、如果将所有字段都建索引会导致索引文件过大,反而降低crud性能。

    三、多使用Profile

    要想优化一条SQL,就必须清楚这条SQL的查询性能瓶颈到底在哪里,是消耗的CPU计算太多还是IO操作太多。通过QUERY Profiler功能,可以分析多种资源的消耗情况,如CPU、IO、IPC、SWAP等,同时还能得到该QUERY执行过程中MySQl所调用的各个函数在源文件中的位置。

    先开启profile功能

    使用命令 set profiling = 1 可以开启关闭的功能。

    开启profile功能后,MySQl就会自动记录所有执行的QUERY的Profile信息。如执行SQL

    查看所有执行的QUERY的Profile信息

    使用命令show profiles 获取当前系统中保存的多个QUERY的profile信息

    获取单个QUERY的详细的profile信息

    show profile cpu,block io,IPC,SOURCE,SWAPS for query Query_ID;

    All 显示所有性能信息
    BLOCK IO 显示块IO操作的次数
    CONTEXT SWITCHES 显示上下文切换次数,不管是主动还是被动
    CPU 显示用户CPU时间、系统CPU时间
    IPC 显示发送和接收的消息数量
    PAGE FAULTS 显示页错误数量
    SOURCE 显示源码中的函数名称与位置
    SWAPS 显示SWAP的次数

  • 相关阅读:
    关于web开发的一点理解
    如何通过Request.ServerVariables["HTTP_USER_AGENT"]获取客户端操作系统信息
    将图片转换为Base64
    asp.net 图片质量压缩(不改变尺寸)
    下载网路图片并保存在硬盘
    HTTP Content-type 对照表
    mssql 查询全部用户创建表 条数及占用空间大小(KB)
    幸运抽奖数据结构
    非UI线程和UI线程通信
    爬取淘宝“手机信息”
  • 原文地址:https://www.cnblogs.com/xsshu/p/10691389.html
Copyright © 2011-2022 走看看