超详细用profile工具分析sql语句执行及status说明

2023-11-03

超详细用profile工具分析sql语句执行及status说明

介绍

sql执行慢的原因有可能很多种,怎么定位呢?可以用Query Profile人工具。通过该工具可以获取一条Query 在整个执行过程中多种资源的消耗情况,如 CPU,IO,IPC,SWAP 等,以及发生的 PAGE FAULTS,CONTEXT SWITCHE 等等,同时还能得到该 Query 执行过程中 MySQL 所调用的各个函数在源文件中的位置。

但是因为它需要调用系统的getrusage()函数,所以只是在Linux/Unix类平台上才能使用,而不能在Windows平台上使用。而且,PROFILING是针对处理进程(process)而不是线程(thread)的,服务器上的其他应用,可能会影响您的调试结果,因此,这个工具适合开发过程中的调试,如果要在生产环境中调试使用,则要注意它的局限性。

操作

mysql> show variables like '%profil%' // 查看profiling监控是否打开
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| have_profiling         | YES   |
| profiling              | OFF   |
| profiling_history_size | 15    |
+------------------------+-------+
mysql> set profiling=1; // 开启profiling监听,注意区分全局变量和session变量,全局用set global profiling
mysql> select * from users where id = 1; // 执行任意sql语句
mysql> show profiles; // 查看记录到的query
+----------+------------+----------------------------+
| Query_ID | Duration   | Query                      |
+----------+------------+----------------------------+
|        1 | 0.00060275 | select * from customers    |
|        2 | 0.00222450 | show tables                |
|        3 | 0.00567425 | select * from offices      |
|        4 | 0.00052050 | show tables                |
|        5 | 0.01123300 | select * from payments     |
|        6 | 0.00111675 | show tables                |
|        7 | 0.02049625 | select * from users where id = 1 |
+----------+------------+----------------------------+
mysql> show profile for query 7;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000043 |
| checking permissions | 0.000005 |
| Opening tables       | 0.014552 |
| init                 | 0.000025 |
| System lock          | 0.000009 |
| optimizing           | 0.000004 |
| statistics           | 0.000011 |
| preparing            | 0.000010 |
| executing            | 0.000003 |
| Sending data         | 0.005653 |
| end                  | 0.000010 |
| query end            | 0.000009 |
| closing tables       | 0.000020 |
| freeing items        | 0.000121 |
| cleaning up          | 0.000023 |
+----------------------+----------+
mysql> show profile block io, cpu for query 7; //获取io和cpu详细消耗信息
mysql> show profile block io, cpu, memory, swaps, context switches, source for query 7; //获取其他详细消耗信息如,内存,虚拟内存,上下文切换

status说明

通过上面的信息,可以看到很多内容,注意mysql show proflie 的 status信息。通过在哪一个status耗时比较长可以帮助我们定位问题。

altering table
服务器正在执行一个ALTER TABLE

checking permissions
线程正在检查服务器是否拥有执行语句所需的权限。

Checking table
线程正在执行一个表检查操作。

cleaning up
线程已经处理了一个命令,并准备释放内存和重置某些状态变量。

Closing tables	
正在将表中修改的数据刷新到磁盘中,同时正在关闭已经用完的表。这是一个很快的操作,如果不是,请检查磁盘是否已满,磁盘是否被大量使用。

copy to tmp table
线程正在处理一条ALTER TABLE语句。这种状态发生在创建了具有新结构的表之后,但在将行复制到该表之前。

Copying to tmp table on disk	
由于临时结果集大于tmp_table_size,正在将临时表从内存存储转为磁盘存储以此节省内存。

deleting from main table
服务器正在执行多表删除的第一部分。它只删除第一个表,并保存用于从其他(引用)表删除的列和偏移量。

deleting from reference tables
服务器正在执行多表删除的第二部分,并从其他表中删除匹配的行。

end
这发生在ALTER TABLECREATE VIEWDELETEINSERTSELECTUPDATE语句清理之前的末尾。
对于结束状态,可能会发生以下操作:
1、修改表中的数据后删除查询缓存项
2、将事件写入二进制日志
3、释放内存缓冲区,包括用于blob的缓冲区

executing
线程开始执行一条语句。

init
这发生在ALTER TABLEDELETEINSERTSELECTUPDATE语句初始化之前。在这种状态下,服务器采取的操作包括清空二进制日志、InnoDB日志和一些查询缓存清理操作。

Killed
发送了一个kill请求给某线程,那么这个线程将会检查kill标志位,同时会放弃下一个kill请求。MySQL会在每次的主循环中检查kill标志位,不过有些情况下该线程可能会过一小段才能死掉。如果该线程程被其他线程锁住了,那么kill请求会在其他线程释放锁时生效。

logging slow query
线程正在向慢查询日志写入一条语句。

manage keys
服务器正在启用或禁用一个表索引。

Opening tables
线程试图打开一个表。这应该是一个非常快的过程,除非有什么东西阻止打开。例如,ALTER TABLELOCK TABLE语句可以阻止打开一个表,直到语句完成。还需要检查table_open_cache值是否足够大。

optimizing
服务器正在对查询执行初始优化。

query end
此状态发生在处理查询之后,但在释放项状态之前。如果发现这里耗时严重,参考end状态的说明

Removing duplicates
查询使用SELECT DISTINCT的方式,MySQL不能在早期阶段优化掉DISTINCT操作。因此,MySQL在将结果发送到客户端之前需要一个额外的阶段来删除所有重复的行。

removing tmp table
线程正在处理一个SELECT语句后删除一个内部临时表。如果没有创建临时表,则不使用此状态。

Receiving from client
服务器正在从客户端读取数据包。在MySQL 5.7.8之前,这个状态叫做Reading from net。

Reopen tables
线程获得了表的锁,但在获得锁后注意到底层表结构发生了变化。它释放了锁,关闭了表,并试图重新打开它。

Rolling back
线程正在回滚事务。

starting
语句执行开始的第一个阶段。

Sending data
线程正在读取和处理SELECT语句的行,并向客户机发送数据。由于在此状态下发生的操作往往会执行大量的磁盘访问(读取),因此在给定查询的生命周期中,它通常是运行时间最长的状态。

Sorting for group
线程正在进行排序,以满足GROUP BY的要求。

Sorting for order
线程正在执行排序以满足ORDER BYstatistics
服务器正在计算统计数据以制定查询执行计划。如果一个线程长时间处于这种状态,那么服务器可能是磁盘绑定的,正在执行其他工作。

System lock
线程调用了mysql_lock_tables(),并且线程状态一直没有更新。这是一种非常普遍的状态,可能由于许多原因而发生。
例如,线程将请求或等待表的内部或外部系统锁。当InnoDB在执行锁表时等待表级锁时,就会发生这种情况。如果这种状态是由外部锁请求引起的,并且您没有使用多个正在访问相同MyISAM表的mysqld服务器,您可以使用——skip-external-locking选项禁用外部系统锁。但是,外部锁定在默认情况下是禁用的,所以这个选项很可能没有效果。对于SHOW PROFILE,这个状态意味着线程正在请求锁(而不是等待锁)update
线程已经准备好开始更新表。

Updating
线程正在搜索要更新的行,并正在更新它们。

updating main table
服务器正在执行多表更新的第一部分。它只更新第一个表,并保存用于更新其他(引用)表的列和偏移量。

updating reference tables
服务器正在执行多表更新的第二部分,并更新来自其他表的匹配行。

User lock
线程正在请求或等待用GET_LOCK()调用请求的建议锁。对于SHOW PROFILE,这个状态意味着线程正在请求锁(而不是等待锁)User sleep
线程调用了一个SLEEP()调用。

Waiting for commit lock
带读锁的FLUSH TABLES正在等待提交锁。

Waiting for global read lock
带读锁的FLUSH TABLES正在等待一个全局读锁,或者正在设置全局read_only系统变量。

Waiting for tables
线程收到一个通知,说表的底层结构发生了变化,它需要重新打开表以获得新的结构。但是,要重新打开表,它必须等待所有其他线程都关闭了相关的表。

Waiting for lock_type lock
服务器正在等待获取THR_LOCK锁或者元数据锁,其中lock_type表示锁的类型。

下面这个状态表示等待THR_LOCK锁:
Waiting for table level lock

下面这些状态表示等待元数据锁(metadata lock)
Waiting for event metadata lock
Waiting for global read lock
Waiting for schema metadata lock
Waiting for stored function metadata lock
Waiting for stored procedure metadata lock
Waiting for table metadata lock
Waiting for trigger metadata lock

案例说明

测试中发现一条insert语句执行居然要耗时70-140MS。通过profile发现在query end耗时居然非常多,一番查询下来,发现有三种情况可以解释上面的状况

硬盘快满了

 首先排除了

sync_binlog=1导致

  • 值为1:事务提交后,将二进制文件写入磁盘并立即执行刷新操作,相当于是同步写入磁盘,不经过操作系统的缓存。虽然能够保证事务原子性,但是验证影响写入速度。和0的写入速度能相差30倍左右。
  • 值为0:默认值。事务提交后,将二进制日志从缓冲写入磁盘,但是不进行刷新操作(fsync()),此时只是写入了操作系统缓冲,若操作系统宕机则会丢失部分二进制日志。
  • 值为N:每写N次操作系统缓冲就执行一次刷新操作。

innodb_flush_log_at_trx_commit=1导致

  • 值为0 : 提交事务的时候,不立即把 redo log buffer 里的数据刷入磁盘文件的,而是依靠 InnoDB 的主线程每秒执行一次刷新到磁盘。此时可能你提交事务了,结果 mysql 宕机了,然后此时内存里的数据全部丢失。
  • 值为1 : 提交事务的时候,就必须把 redo log 从内存刷入到磁盘文件里去,只要事务提交成功,那么 redo log 就必然在磁盘里了。注意,因为操作系统的“延迟写”特性,此时的刷入只是写到了操作系统的缓冲区中,因此执行同步操作才能保证一定持久化到了硬盘中。
  • 值为2 : 提交事务的时候,把 redo 日志写入磁盘文件对应的 os cache 缓存里去,而不是直接进入磁盘文件,可能 1 秒后才会把 os cache 里的数据写入到磁盘文件里去。
  • 可以看到,只有1才能真正地保证事务的持久性是由于刷新操作 fsync() 是阻塞的,直到完成后才返回,我们知道写磁盘的速度是很慢的,因此 MySQL 的性能会明显地下降。如果不在乎事务丢失,0和2能获得更高的性能

最后发现和sync_binlog=1强相关,改为0以后写入速度有显著提升。但是该选项的设置还要根据具体业务场景来确定用什么策略比较合适。

要废弃

但是,从5.7版本的refman文档(mysql-refman-5.7)就有在说明这两个命令会废弃掉,要用其他performance schema替代。

Note
The SHOW PROFILE and SHOW PROFILES statements are deprecated; expect them to be removed in a future MySQL release. Use the Performance Schema instead; see Section 25.19.1, “Query Profiling Using Performance Schema”.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

超详细用profile工具分析sql语句执行及status说明 的相关文章

  • mysql中的按位移位

    如何在 MySQL 中进行按位移位 有没有具体的指令或者操作符 如果不是 如何最佳地模拟它 看一下按位运算符MySQL first http dev mysql com doc refman 5 0 en bit functions htm
  • 如何在 SQL 中存储目标(例如 RPG Quest)

    今天有人问我他们应该如何将任务目标存储在 SQL 数据库中 在这种情况下 请考虑角色扮演游戏 目标可能包括以下一些内容 发现 地点 杀死 n MOB 类型 获取 对象 的 n 个 实现 技能组 中的 技能 你在角色扮演游戏中获得的所有其他东
  • 是否可以在MYSQL中动态选择列名,其中列名是N个已知值中的1?

    我担心答案会是直接的 不 但我想知道是否可以在 MySQL 中执行如下操作 SELECT title label name FROM table 即选择单个列 可以称为title label or name from table 原因是 查
  • AttributeError:尝试在 python 中运行 sqlalchemy 来管理我的 SQL 数据库时,“Engine”对象没有属性“execute”

    我有以下代码行不断给我一个错误 即引擎对象没有对象执行 我认为我一切都对 但不知道接下来会发生什么 似乎其他人也遇到了这个问题 重新启动他们的笔记本电脑就可以了 我正在使用 Pycharm 并已重新启动但没有任何解决方案 任何帮助是极大的赞
  • Crystal Reports 相当于“WHERE”

    我熟悉 SQL 但不熟悉 Crystal Reports 我正在尝试处理包含 5 列的导入数据集 id deathDate giftDate giftAmount Dead 123 2008 01 06 2011 09 08 25 00 T
  • MySQL 获取时间优化

    o我有一个包含 200 万个寄存器的表 但它很快就会增长得更多 基本上 该表包含具有相应描述符的图像的兴趣点 当我尝试执行选择在空间上靠近查询点的点的查询时 总执行时间花费太长 更准确地说 持续时间 获取 0 484 秒 27 441 秒
  • 更新\插入数据从grafana到mysql

    可以从grafana更新数据或插入数据到mysql 我需要使用 UI 在 mysql 中插入 更新信息 现在我已经在使用grafana 所以想知道是否有任何方法可以使用grafana来更新或插入信息 没有用于获取用户输入并将该数据插入 My
  • 如何查询多个链接服务器?

    链接一些 SQL Server 2008 服务器 实例后 我想对这些服务器进行更通用的查询 我知道我必须像这样指定查询的命运 select from SRV INSTANCE dbname dbo foo 但是 我会针对多个链接服务器运行此
  • SQL 事务如何工作?

    我从事 SQL 工作的时间并不长 但我想我明白 通过将 SQL 语句包装在事务中 所有语句都会完成 或者都不会完成 这是我的问题 我有一个包含 lineitem 集合的订单对象 行项目在 order OrderId 上相关 我已经证实所有
  • Mac OS X Yosemite/El Capitan 上自动启动 MySQL 服务器

    我想在启动时自动启动 MySQL 服务器 这在小牛队是可能的 但在优胜美地似乎不起作用 edit 似乎这也适用于 El Capitan dcc 非常接近 这是 MySQL 在 Yosemite 上再次自动启动的方式 The com mysq
  • 为什么将 MySQL 凭据放在 www 目录之外? [复制]

    这个问题在这里已经有答案了 可能的重复 将核心类放在 Web 根目录之上 好还是坏主意 https stackoverflow com questions 3648739 putting core classes above the web
  • Django 查询:“datetime + delta”作为表达式

    好吧 我的问题如下 假设我有下一个模型 这是一个简单的情况 class Period models Model name CharField field specs here start date DateTimeField field s
  • PostgreSQL 如何创建数据库或模式的副本?

    有没有一种简单的方法可以在 PostgreSQL 8 1 中创建数据库或模式的副本 我正在测试一些软件 它对数据库中的特定模式进行大量更新 我想复制它 以便我可以与原始版本进行一些比较 如果它位于同一服务器上 则只需使用带有 TEMPLAT
  • 将错误保存到 MySQL 数据库

    我有一个 php 查询来更新 MySQL 数据库 请参见下文 sql update hr payroll set payroll number payroll number tax code tax bacs ref bacs ref pa
  • Drupal 视图 - 自定义/修改 SQL

    我遇到了 配置文件复选框 模块的问题 该模块存储以逗号分隔的自定义配置文件字段 问题是我是否创建一个视图来按值过滤 SQL 结果最终是这样的 AND profile values profile interests value in Bus
  • 如何查找列中未使用的ID? [复制]

    这个问题在这里已经有答案了 可能的重复 SQL查询查找丢失的序列号 https stackoverflow com questions 1057389 sql query to find missing sequence numbers 我
  • CakePHP - 获取上次运行的查询

    我想获取 CakePHP 运行的最后一个查询 我无法在 core php 中打开调试 也无法在本地运行代码 我需要一种方法来获取最后一个 sql 查询并将其记录到错误日志中而不影响实时站点 该查询失败但正在运行 像这样的事情会很棒 this
  • 选定的非聚合值必须是关联组的一部分

    我在 Teradata 中有两个表 Table A 和 Table B 它们之间是 LEFT JOIN 之后我将创建 SELECT 语句 其中包含两个表中的属性 SELECT attribute 1 attribute 2 attribut
  • 返回年份数组作为年份范围

    我正在尝试查询一个包含以下内容的表character varying 年份列 并将这些年份作为逗号分隔的年份范围字符串返回 年份范围将由数组中存在的连续年份确定 不连续的年份 年份范围应以逗号分隔 数据类型的原因是character var
  • 字符串文字上的 SQL Server T-SQL N 前缀[重复]

    这个问题在这里已经有答案了 这可能是一个菜鸟问题 但我发现了一些 T SQL 查询示例来验证数据库大小SELECT and WHERE clause here http technet microsoft com en us library

随机推荐

  • flutter 怎么实现app整体灰度

    今天举国哀悼 进入各种大厂的app也可以看到主色都变成灰色的了 作为程序员我们肯定会想怎么可以实现的 我简单研究了10分钟 flutter中只要在整体外面套一个ShaderMask 然后修改blendMode即可 核心代码 class My
  • CentOS7目录结构详细版

    原文地址 http www cnblogs com ellisonDon archive 2012 10 03 2710730 html 原文地址 https www cnblogs com ellisonDon archive 2012
  • SpringBoot集成ShardingJDBC系列【2】—— 基于yaml基本配置

    文章只负责讲解sharding的相关配置 springboot其他的配置自己解决 文章内容将分开发布 便于平时查阅 基于yaml基本配置 在application yml配置文件中对mybatis plus做简单的配置 这里不对Mybati
  • Flutter设置Container的高度随ListView或者GridView

    在做移动端的时候 很多时候会需要下图所示的需求 如图1美团外卖首页的一部分 先进行需求分析 这个模块可以设计成Container包含GridView GridView中子内容个数由后台数据控制 但是在直接写Container包含GridVi
  • 第130篇 在 OpenSea 上创建自己的 NFT 商店(2)

    本文介绍一种通过自己部署智能合约 在 OpenSea 上创建自己的 NFT 商店的方法 1 ERC721合约 写一个最简单的标准 ERC721 合约 源码 SPDX License Identifier MIT pragma solidit
  • java 简介

    java 简介 1991 年Sun公司的James Gosling 詹姆斯 高斯林 等人开始开发名称为 Oak 的语言 希望用于控制嵌入在有线电视交换盒 PDA等的微处理器 1994年将Oak语言更名为Java 1 java体系结构 j2s
  • C语言笔记 指针 数组

    C语言中 指针做函数参数传递二维数组有两种基本方法 1 传递 数组指针 include
  • Openstack常用命令

    目录 一 创建用户 二 创建删除模板和模板其他操作 三 创建更新删除镜像 四 创建网络 五 VPN的使用 六 创建容器swift模块 前言 在linux中使用openstakc命令前 需要source etc keystone admin
  • 设计模式在开源框架中的应用

    设计模式不是虚的 实实在在出现在很多开源框架中 比如spring tomcat等等 现在这篇文章是一个阅读合集 整理了设计模式在开源框架中的应用 后续会逐渐补充 1 tomcat中设计模式的使用 Tomcat 系统架构与设计模式 第 2 部
  • 最大期望值(EM算法)学习

    20201008 0 引言 提示 本篇文章并没有详细的说明EM算法数学推导 虽然前面通过GMM的例子能够明白大致的思想 但是在底层数学推导部分没有非常完整说明 后续有时间可能会继续添加 如果想知道数学原理的读者 就不要浪费时间再看这篇文章了
  • TCP/IP学习笔记-PPPoE协议

    写在前面 仅供学习使用 PPPoE协议概述 PPPoE是一种把PPP帧封装到以太网帧的链路层协议 所以抓包的时候抓的是以太网协议 PPPoE利用以太网将大量主机组网 不仅具有以太网快速简便的特点还有PPP强大的功能 任何能被PPP封装的协议
  • OLED拼接屏生产流程全解析:关键步骤、注意事项和技术趋势

    OLED拼接屏作为现代商业展示 会议室和指导系统中的重要组成部分 其高亮度 高对比度和逼真的色彩效果备受推崇 然而 要实现一块完美无缝的OLED拼接屏并非易事 本文将深入探讨OLED拼接屏的生产过程 包括关键步骤 注意事项以及当前的技术趋势
  • Spring Cloud Gateway 远程代码执行漏洞(CVE-2022-22947)

    一 漏洞描述 Spring Cloud Gateway 是基于 Spring Framework 和 Spring Boot 构建的网关 它旨在为微服务架构提供一种简单 有效 统一的 API 路由管理方式 3月1日 VMware发布安全公告
  • Linux三剑客(grep、sed、awk)

    Linux三剑客指的是grep sed awk 其中grep擅长查找功能 sed擅长取行和替换 awk擅长取列 一 grep grep作用是筛选 查询 文本搜索工具 根据用户指定的 模式 pattern 对目标文本进行过滤 显示被模式匹配到
  • bp神经网络算法matlab程序,bp神经网络的matlab实现

    MATLAB中BP神经网络的训练算法具体是怎么样的 先用newff函数建立网络 再用train函数训练即可 1 正向传播 输入样本 gt 输入层 gt 各隐层 处理 gt 输出层注1 若输出层实际输出与期望输出 教师信号 不符 则转入2 误
  • MATLAB批量重命名存储数据

    目录 文件查找 文件移动和改名 所调用函数功能 文件查找 首先确定数据存储的文件夹地址 记为folder dir 如果该文件夹不存在需要访问的子文件夹 则直接复制文件地址 如果存在需要访问的子文件夹 则要利用dir函数进行寻找 将子文件夹信
  • Content-Type

    要学习content type 必须事先知道它到底是什么 是干什么用的 HTTP协议 RFC2616 采用了请求 响应模型 客户端向服务器发送一个请求 请求头包含请求的方法 URI 协议版本 以及包含请求修饰符 客户 信息和内容的类似于MI
  • SQL综合案例之电商漏斗转化分析,pv,uv及

    漏斗模型示例 不同的业务场景有不同的业务路径 有先后顺序 事件可以出现多次 注册转化漏斗 启动APP gt APP注册页面 gt 注册结果 gt 提交订单 gt 支付成功 搜购转化漏斗 搜索商品 gt 点击商品 gt 加入购物车 gt 提交
  • 什么是UTXO

    比特币UTXO是比特币网络中的一个重要概念 它是比特币交易的基础 也是比特币的账户系统 本文将从UTXO的定义 使用方式 优点和缺点等多个方面详细介绍比特币UTXO 一 UTXO的定义 UTXO Unspent Transaction Ou
  • 超详细用profile工具分析sql语句执行及status说明

    超详细用profile工具分析sql语句执行及status说明 介绍 sql执行慢的原因有可能很多种 怎么定位呢 可以用Query Profile人工具 通过该工具可以获取一条Query 在整个执行过程中多种资源的消耗情况 如 CPU IO