MySQL剖析单条查询
2024-10-06 18:47:06
使用SHOW PROFILE
SHOW PROFILE命令默认是禁用的,可以通过以下命令修改
SET profiling=1;
当一条查询提交给服务器时,,此工具会记录剖析信息到一张临时表,并且给查询一个从1开始的整数标识符
SELECT * from poem_config;
```sql
SHOW PROFILES;
```
结果
master >show profiles;
+----------+------------+---------------------------+
| Query_ID | Duration | Query |
+----------+------------+---------------------------+
| 1 | 0.00030575 | select * from poem_config |
+----------+------------+---------------------------+
这里可以看到查询执行的精确时间,这个时间是总的时间
SHWO PROFILE FOR QUERY 1
结果
master >show profile for query 1;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000057 |
| checking permissions | 0.000008 |
| Opening tables | 0.000017 |
| init | 0.000021 |
| System lock | 0.000009 |
| optimizing | 0.000004 |
| statistics | 0.000012 |
| preparing | 0.000011 |
| executing | 0.000003 |
| Sending data | 0.000121 |
| end | 0.000005 |
| query end | 0.000007 |
| closing tables | 0.000008 |
| freeing items | 0.000013 |
| cleaning up | 0.000011 |
+----------------------+----------+
剖析报告给出了查询执行的每个步骤及其花费的时间,通过这个报告我们可以确定哪些步骤耗时较长,从而找到对应的优化方法。
使用SHOW STATUS
MySQL的SHOW STATUS命令返回一些计数器,这些计数器可以显示某些活动如读索引的频繁程度,但无法给出消耗了多少时间。
尽管SHOW STATUS无法提供基于时间的统计,但对于执行完查询后观察某些计数器的值还是有帮助的。有时候我们可以从这些值里面猜测哪些代价较高或者消耗的时间较多。
最有用的计数器包括句柄计数器(handler counter)、临时文件和表计数器
示例:
我们先将临时会话级别的计数器重置为0,然后执行查询,再检查计数器的结果
FLUSH STATUS;
SELECT * FROM poem_config;
SHOW STATUS WHERE Variable_name LIKE 'Handler%'
OR Variable_name LIKE 'Created%';
结果
master >SHOW STATUS WHERE Variable_name LIKE 'Handler%'
-> OR Variable_name LIKE 'Created%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Created_tmp_disk_tables | 0 |
| Created_tmp_files | 0 |
| Created_tmp_tables | 0 |
| Handler_commit | 1 |
| Handler_delete | 0 |
| Handler_discover | 0 |
| Handler_external_lock | 2 |
| Handler_mrr_init | 0 |
| Handler_prepare | 0 |
| Handler_read_first | 1 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 0 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 20 |
| Handler_rollback | 0 |
| Handler_savepoint | 0 |
| Handler_savepoint_rollback | 0 |
| Handler_update | 0 |
| Handler_write | 0 |
+----------------------------+-------+
从结果你可以看到,查询没有使用临时表,并且有较多的没有用到索引的读操作(Handler_read_rnd_next),Handler_read_rnd_next的值为20,整个表里的数据也是20条,说明是全表扫描。
未完待续...
最新文章
- Linux C 信号 pause、sigsuspend 的相同与区别
- 【BZOJ】1934: [Shoi2007]Vote 善意的投票(网络流/-二分图匹配)
- Python 练习 11
- System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
- 【第七篇】bootstrap的3级菜单样式,支持母版页保留打开状态
- 如何使用nodejs发邮件
- 关于Mysql索引的笔记
- org.springframework.core.io包内的源码分析
- Mac系统下XAMPP的简单使用
- Servlet实践--HelloWorld
- Monggodb基础
- vue项目中主要文件的加载顺序(index.html、App.vue、main.js)
- Linux-Centos7 安装图形界面
- perl6 Net::HTTP 发送任意 url 请求例子
- javascript按照指定格式获取上一个月的日期
- day11<;Java开发工具&;常见对象>;
- Template类的使用指南【python】
- OpenCV&;&;python_图像平滑(Smoothing Images)
- 题解 P1478 【陶陶摘苹果(升级版)】
- vue 子父组件之间的通信,及在调用组件的地方