• 【MySQL】分析SQL的几种方式


    一、查看SQL执行频率

    show session status:显示 session 级的统计结果(不写参数默认session)

    show global status:显示 global 级的统计结果

    mysql> show status like 'Com_______';   -- 查看各种类型SQL的执行次数
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | Com_binlog    | 0     |
    | Com_commit    | 2     |
    | Com_delete    | 0     |
    | Com_import    | 0     |
    | Com_insert    | 35    |
    | Com_repair    | 0     |
    | Com_revoke    | 0     |
    | Com_select    | 13    |
    | Com_signal    | 0     |
    | Com_update    | 0     |
    | Com_xa_end    | 0     |
    +---------------+-------+
    11 rows in set (0.00 sec)
    
    mysql> show global status like 'Com_______';   -- 查看各种类型SQL的执行次数
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | Com_binlog    | 0     |
    | Com_commit    | 4     |
    | Com_delete    | 4     |
    | Com_import    | 0     |
    | Com_insert    | 35    |
    | Com_repair    | 0     |
    | Com_revoke    | 0     |
    | Com_select    | 291   |
    | Com_signal    | 0     |
    | Com_update    | 11    |
    | Com_xa_end    | 0     |
    +---------------+-------+
    11 rows in set (0.00 sec)
    
    mysql> show status like 'Innodb_rows_%';
    +----------------------+-------+
    | Variable_name        | Value |
    +----------------------+-------+
    | Innodb_rows_deleted  | 0     |   -- 删除的行数
    | Innodb_rows_inserted | 0     |   -- 插入的行数
    | Innodb_rows_read     | 0     |   -- 读取的行数
    | Innodb_rows_updated  | 0     |   -- 更新的行数
    +----------------------+-------+
    4 rows in set (0.00 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    参数含义
    Com_select执行 select 操作的次数,一次查询只累加 1。
    Com_insert执行 INSERT 操作的次数,对于批量插入的 INSERT 操作,只累加一次。
    Com_update执行 UPDATE 操作的次数。
    Com_delete执行 DELETE 操作的次数。
    Innodb_rows_readselect 查询返回的行数。
    Innodb_rows_inserted执行 INSERT 操作插入的行数。
    Innodb_rows_updated执行 UPDATE 操作更新的行数。
    Innodb_rows_deleted执行 DELETE 操作删除的行数。
    Connections试图连接 MySQL 服务器的次数。
    Uptime服务器工作时间。
    Slow_queries慢查询的次数。

    Com_xxx :这些参数对于所有存储引擎的表操作都会进行累计。

    Innodb_xxx :这几个参数只是针对InnoDB 存储引擎的,累加的算法也略有不同。

    二、定位低效率执行SQL

    1. show processlist

    查看当前MySQL在进行的线程,包括线程的状态、是否锁表等,可以实时地查看 SQL 的执行情况,同时对一些锁表操作进行优化

    在这里插入图片描述

    1) id列,用户登录mysql时,系统分配的"connection_id",可以使用函数connection_id()查看

    2) user列,显示当前用户。如果不是root,这个命令就只显示用户权限范围的sql语句

    3) host列,显示这个语句是从哪个ip的哪个端口上发的,可以用来跟踪出现问题语句的用户

    4) db列,显示这个进程目前连接的是哪个数据库

    5) command列,显示当前连接的执行的命令,一般取值为休眠(sleep),查询(query),连接(connect)等

    6) time列,显示这个状态持续的时间,单位是秒

    7) state列,显示使用当前连接的sql语句的状态,很重要的列。state描述的是语句执行中的某一个状态。一个sql语句,以查询为例,可能需要经过copying to tmp table、sorting result、sending data等状态才可以完成

    8) info列,显示这个sql语句,是判断问题语句的一个重要依据

    2. 慢查询日志

    通过慢查询日志定位那些执行效率较低的 SQL 语句,用–log-slow-queries[=file_name]选项启动时,mysqld 写一个包含所有执行时间超过 long_query_time 秒的 SQL 语句的日志文件

    MySQL Server 层四个日志

    三、explain分析执行计划

    列名描述
    id在一个大的查询语句中每个SELECT关键字都对应一个 唯一的id
    select_typeSELECT关键字对应的那个查询的类型
    table表名
    partitions匹配的分区信息
    type *针对单表的访问方法
    possible_keys可能用到的索引
    key *实际上使用的索引
    key_len *实际使用到的索引长度
    ref当使用索引列等值查询时,与索引列进行等值匹配的对象信息
    rows *预估的需要读取的记录条数
    filtered某个表经过搜索条件过滤后剩余记录条数的百分比
    Extra *一些额外的信息,排序…

    type

    完整的访问方法如下: system ,const ,eq_ref ,ref ,fulltext ,ref_or_null ,index_merge , unique_subquery ,index_subquery , range , index ,ALL

    • const:当我们根据主键或者唯一二级索引列与常量等值匹配时,对单表的访问方法就是const,只匹配一条记录
    • ref:普通二级索引等值匹配常量
    • range:走索引的范围查询
    • index_merge:用到多个索引(多个select,比如子查询)
    • index:需要扫描整个索引树(比如联合索引只用到右边的字段,和查询数据可以组成联合索引)
    • ALL:不走索引,全表扫描,读磁盘

    key: 用到的索引

    key_len: 用到索引的占用的字节数,针对联合索引有一定的参考价值

    ref

    • const:常量等值匹配

    rows: 预估需要读取的记录数,越小越好

    Extra

    • using filesort:排序
    • using index:表示使用索引,且没有回表(覆盖索引)
    • using where:表示使用索引,且需要回表
    • using index condition:索引下推
    1. id

    1) id 相同表示加载表的顺序是从上到下

    explain select * from t_role r, t_user u, user_role ur where r.id = ur.role_id and u.id = ur.user_id ;
    
    • 1

    在这里插入图片描述

    2) id 不同id值越大,优先级越高,越先被执行

    EXPLAIN SELECT * FROM t_role WHERE id = (SELECT role_id FROM user_role WHERE user_id = (SELECT id FROM t_user WHERE username = 'stu1'))
    
    • 1

    在这里插入图片描述

    3) id 有相同,也有不同。id相同的可以认为是一组,从上往下顺序执行;在所有的组中,id的值越大,优先级越高,越先执行

    EXPLAIN SELECT * FROM t_role r , (SELECT * FROM user_role ur WHERE ur.`user_id` = '2') a WHERE r.id = a.role_id ; 
    
    • 1

    在这里插入图片描述

    2. select_type

    表示 SELECT 的类型,常见的取值,如下表所示:

    select_type含义
    SIMPLE简单的select查询,查询中不包含子查询或者UNION
    PRIMARY查询中若包含任何复杂的子查询,最外层查询标记为该标识
    SUBQUERY在SELECT 或 WHERE 列表中包含了子查询
    DERIVED在FROM 列表中包含的子查询,被标记为 DERIVED(衍生) MYSQL会递归执行这些子查询,把结果放在临时表中
    UNION若第二个SELECT出现在UNION之后,则标记为UNION ; 若UNION包含在FROM子句的子查询中,外层SELECT将被标记为 : DERIVED
    UNION RESULT从UNION表获取结果的SELECT

    在这里插入图片描述

    在这里插入图片描述

    3. type

    type 显示的是访问类型,是较为重要的一个指标,可取值为:

    type含义
    NULLMySQL不访问任何表,索引,直接返回结果
    system表只有一行记录(等于系统表),这是const类型的特例,一般不会出现
    const表示通过索引一次就找到了,const 用于比较primary key 或者 unique 索引。因为只匹配一行数据,所以很快。如将主键置于where列表中,MySQL 就能将该查询转换为一个常亮。const于将 “主键” 或 “唯一” 索引的所有部分与常量值进行比较
    eq_ref类似ref,区别在于使用的是唯一索引,使用主键的关联查询,关联查询出的记录只有一条。常见于主键或唯一索引扫描
    ref非唯一性索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,返回所有匹配某个单独值的所有行(多个)
    range只检索给定返回的行,使用一个索引来选择行。 where 之后出现 between , < , > , in 等操作。
    indexindex 与 ALL的区别为 index 类型只是遍历了索引树, 通常比ALL 快, ALL 是遍历数据文件。
    all将遍历全表以找到匹配的行

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

    system > const > eq_ref > ref > range > index > ALL

    4. key

    possible_keys : 显示可能应用在这张表的索引, 一个或多个。

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

    key_len : 表示索引中使用的字节数, 该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下, 长度越短越好 。

    5. extra
    • using filesort:说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取, 称为 “文件排序”,效率低
    • using temporary:使用了临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于 order by 和 group by; 效率低
    • using where:表示使用索引,且需要回表
    • using index:表示相应的select操作使用了覆盖索引, 避免访问表的数据行, 效率不错
    • using index condition:联合索引生效,但是需要回表,并没有用到覆盖索引,需要优化,避免使用select *

    四、show profile

    开启profiling 开关:set profiling=1;

    执行完SQL后,再执行show profiles 指令, 来查看SQL语句执行的耗时:

    在这里插入图片描述

    通过show profile for query [query_id] 语句可以查看到该SQL执行过程中每个线程的状态和消耗的时间:

    在这里插入图片描述

  • 相关阅读:
    Centos 7 部署SVN服务器
    4核8G服务器腾讯云CVM S5性能如何?CPU型号及租用价格
    ceph 原理
    Vuex 状态管理
    2018版USBASP烧录器改通用版教程
    技术干货 | PACMOO:基于帕累托最优的公平性约束协同过滤算法
    Matplotlib二维箭头图
    JS创建对象的十种方式
    ue5创建地图瓦片
    vue3嵌套路由keep-alive问题
  • 原文地址:https://blog.csdn.net/qq_42500831/article/details/133878327