0227浅谈MySQL之 Handler_read_*参数
转自博客http://www.path8.net/tn/archives/5613
1.监控语法:
在MySQL里,使用SHOW STATUS查询服务器状态,语法一般来说如下:
SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern' | WHERE expr]
执行命令后会看到很多内容,其中有一部分是Handler_read_*,它们显示了数据库处理SELECT查询语句的状态,对于调试SQL语句有很大意义。
mysql> show session status like 'Handler_read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 1 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
7 rows in set (0.00 sec)
2.测试流程及用例
每次执行SQL时按照如下过程执行:
FLUSH STATUS;
SELECT ...;
SHOW SESSION STATUS LIKE 'Handler_read%';
EXPLAIN SELECT ...;
测试用例:
mysql> show create table artist\G;
*************************** 1. row ***************************
Table: artist
Create Table: CREATE TABLE `artist` (
`artist_id` int(10) unsigned NOT NULL,
`type` enum('Band','Person','Unknown','Combination') NOT NULL,
`name` varchar(255) NOT NULL,
`name_reverse` varchar(255) DEFAULT NULL,
`gender` enum('Male','Female') DEFAULT NULL,
`founded` year(4) DEFAULT NULL,
`country_id` smallint(5) unsigned DEFAULT NULL,
PRIMARY KEY (`artist_id`),
KEY `name` (`name`),
KEY `idx_founded` (`founded`),
KEY `type` (`type`),
KEY `idx_name_reverse` (`name_reverse`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
3.参数测试
3.1 Handler_read_first
Handler_read_first原意:The number of times the first entry in an index was read. If this value is high, it suggests that the server is doing a lot of full index scans; for example, SELECT col1 FROM foo, assuming that col1 is indexed.
此选项表明SQL是在做一个全索引扫描,注意是全部,而不是部分,所以说如果存在WHERE语句,这个选项是不会变的。如果这个选项的数值很大,既是好事也是坏事。说它好是因为毕竟查询是在索引里完成的,而不是数据文件里,说它坏是因为大数据量时,即使是索引文件,做一次完整的扫描也是很费时间的。
mysql> flush status;
Query OK, 0 rows affected (0.00 sec)
mysql> select name from artist;
......
577983 rows in set (1.50 sec)
mysql> show session status like 'Handler_read%';
ERROR 1317 (70100): Query execution was interrupted
mysql> show session status like 'Handler_read%';
+-----------------------+--------+
| Variable_name | Value |
+-----------------------+--------+
| Handler_read_first | 1 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 577983 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+--------+
7 rows in set (0.00 sec)
mysql> explain select name from artist\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: artist
type: index
possible_keys: NULL
key: name
key_len: 257
ref: NULL
rows: 585801
Extra: Using index
1 row in set (0.00 sec)
使用了只读索引。
3.2 Handler_read_key
Handler_read_key原意:The number of requests to read a row based on a key. If this value is high, it is a good indication that your tables are properly indexed for your queries.
此选项数值如果很高,那么恭喜你,你的系统高效的使用了索引,一切运转良好。
mysql> flush status;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from artist where name='Enya';
+-----------+--------+------+--------------+--------+---------+------------+
| artist_id | type | name | name_reverse | gender | founded | country_id |
+-----------+--------+------+--------------+--------+---------+------------+
| 88 | Person | Enya | aynE | Female | 1961 | 103 |
+-----------+--------+------+--------------+--------+---------+------------+
1 row in set (0.00 sec)
mysql> show session status like 'Handler_read%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 1 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
7 rows in set (0.00 sec)
mysql> explain select * from artist where name='Enya'\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: artist
type: ref
possible_keys: name
key: name
key_len: 257
ref: const
rows: 1
Extra: Using index condition
1 row in set (0.00 sec)
使用了索引下推技术。
3.3 Handler_read_last
Handler_read_last的原意:The number of requests to read the last key in an index. With ORDER BY, the server will issue a first-key request followed by several next-key requests, whereas with ORDER BY DESC, the server will issue a last-key request followed by several previous-key requests. This variable was added in MySQL 5.6.1.
3.4 Handler_read_next
Handler_read_next的原意:The number of requests to read the next row in key order. This value is incremented if you are querying an index column with a range constraint or if you are doing an index scan.
此选项表明在进行索引扫描时,按照索引从数据文件里取数据的次数。
mysql> flush status;
Query OK, 0 rows affected (0.00 sec)
mysql> select name from artist order by name;
......
577983 rows in set (1.55 sec)
mysql> show session status like 'Handler_read%';
+-----------------------+--------+
| Variable_name | Value |
+-----------------------+--------+
| Handler_read_first | 1 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 577983 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+--------+
7 rows in set (0.00 sec)
mysql> explain select name from artist order by name\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: artist
type: index
possible_keys: NULL
key: name
key_len: 257
ref: NULL
rows: 585801
Extra: Using index
1 row in set (0.00 sec)
3.4 Handler_read_prev
Handler_read_prev的原意:The number of requests to read the previous row in key order. This read method is mainly used to optimize ORDER BY ... DESC.
此选项表明在进行索引扫描时,按照索引倒序从数据文件里取数据的次数,一般就是ORDER BY ... DESC。注意Handler_read_next是ORDER BY ... ASC的方式取数据。
mysql> flush status;
Query OK, 0 rows affected (0.00 sec)
mysql> select name from artist order by name desc;
......
577983 rows in set (1.55 sec)
mysql> show session status like 'Handler_read%';
+-----------------------+--------+
| Variable_name | Value |
+-----------------------+--------+
| Handler_read_first | 0 |
| Handler_read_key | 1 |
| Handler_read_last | 1 |
| Handler_read_next | 0 |
| Handler_read_prev | 577983 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+--------+
7 rows in set (0.00 sec)
mysql> explain select name from artist order by name desc\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: artist
type: index
possible_keys: NULL
key: name
key_len: 257
ref: NULL
rows: 585801
Extra: Using index
1 row in set (0.00 sec)
3.5 Handler_read_rnd
Handler_read_rnd的原意:The number of requests to read a row based on a fixed position. This value is high if you are doing a lot of queries that require sorting of the result. You probably have a lot of queries that require MySQL to scan entire tables or you have joins that do not use keys properly.
简单的说,就是查询直接操作了数据文件,很多时候表现为没有使用索引或者文件排序。
mysql> flush status;
Query OK, 0 rows affected (0.00 sec)
mysql> flush status;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from artist order by country_id asc;
577983 rows in set (1.54 sec)
mysql> show session status like 'Handler_read%';
ERROR 1317 (70100): Query execution was interrupted
mysql> show session status like 'Handler_read%';
+-----------------------+--------+
| Variable_name | Value |
+-----------------------+--------+
| 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 | 577984 |
+-----------------------+--------+
7 rows in set (0.00 sec)
mysql> explain select country_id from artist order by country_id asc\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: artist
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 585801
Extra: Using filesort
1 row in set (0.00 sec)
3.6 Handler_read_rnd_next
Handler_read_rnd_next表示“在数据文件中读下一行的请求数。如果你正进行大量的表扫描,该值较高。通常说明你的表索引不正确或写入的查询没有利用索引。”
这个说明跟你的SQL语句有很大的关系,你可以通过explain工具或者是慢查询日志找出对应的慢SQL,并对执行慢的SQL语句进行调试,直到找到最优的执行计划,这样Handler_read_rnd_next的值就会往下降了。
很多时候,为了完成一个查询任务,我们往往可以写出几种查询语句,这时,你不妨挨个按照上面的方式执行,根据结果中的Handler_read_*数值,你就能相对容易的判断各种查询方式的优劣。
还有一种监控的方法就是profile
mysql> show variables like 'profil%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| profiling | OFF |
| profiling_history_size | 15 |
+------------------------+-------+
2 rows in set (0.01 sec)
mysql> set profiling=on;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show profiles;
+----------+------------+-------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-------------------------------------------------------+
| 1 | 2.94708450 | select country_id from artist order by country_id asc |
+----------+------------+-------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> show profile;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000201 |
| checking permissions | 0.000023 |
| Opening tables | 0.000062 |
| init | 0.000069 |
| System lock | 0.000035 |
| optimizing | 0.000011 |
| statistics | 0.000030 |
| preparing | 0.000019 |
| Sorting result | 0.000014 |
| executing | 0.000010 |
| Sending data | 0.000044 |
| Creating sort index | 1.601273 |
| end | 0.000070 |
| query end | 0.000026 |
| closing tables | 0.000029 |
| freeing items | 1.344915 |
| logging slow query | 0.000207 |
| cleaning up | 0.000048 |
+----------------------+----------+
18 rows in set, 1 warning (0.00 sec)
0227浅谈MySQL之 Handler_read_*参数的更多相关文章
- 浅谈mysql配置优化和sql语句优化【转】
做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...
- 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载
浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...
- 浅谈mysql主从复制的高可用解决方案
1.熟悉几个组件(部分摘自网络)1.1.drbd —— DRBD(Distributed Replicated Block Device),DRBD号称是 "网络 RAID" ...
- 浅谈mysql innodb缓存策略
浅谈mysql innodb缓存策略: The InnoDB Buffer Pool Innodb 持有一个存储区域叫做buffer pool是为了在内存中缓存数据和索引,知道innodb buffe ...
- 浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景
浅谈Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁 ...
- (转)运维角度浅谈MySQL数据库优化
转自:http://lizhenliang.blog.51cto.com/7876557/1657465 一个成熟的数据库架构并不是一开始设计就具备高可用.高伸缩等特性的,它是随着用户量的增加,基础架 ...
- 运维角度浅谈MySQL数据库优化(转)
一个成熟的数据库架构并不是一开始设计就具备高可用.高伸缩等特性的,它是随着用户量的增加,基础架构才逐渐完善.这篇博文主要谈MySQL数据库发展周期中所面临的问题及优化方案,暂且抛开前端应用不说,大致分 ...
- 从运维角度浅谈 MySQL 数据库优化
一个成熟的数据库架构并不是一开始设计就具备高可用.高伸缩等特性的,它是随着用户量的增加,基础架构才逐渐完善.这篇博文主要谈MySQL数据库发展周期中所面临的问题及优化方案,暂且抛开前端应用不说,大致分 ...
- 浅谈MySQL存储引擎-InnoDB&MyISAM
存储引擎在MySQL的逻辑架构中位于第三层,负责MySQL中的数据的存储和提取.MySQL存储引擎有很多,不同的存储引擎保存数据和索引的方式是不同的.每一种存储引擎都有它的优势和劣势,本文只讨论最常见 ...
随机推荐
- Spring+Mybatis之注册功能demo
这次先注册功能的是基于登录之后,所以很多配置,实体类等就不再赘述了. 首先也不是直接在地址栏输入一个网页就可以到注册页面的.而是需要通过后台发送一个请求从而跳转到注册页面 先写注册页面,body部分 ...
- codeforce1046 Bubble Cup 11 - Finals 题解
比赛的时候开G开了3h结果rose说一句那唯一一个AC的是羊的心态就崩了.. 这套题感觉质量挺好然后就back了下 A: AI robots 有三个限制条件:相互能够看见和智商的差.使用主席树,可以维 ...
- WingIDE4.1 破解及支持中文设置
1.下面提供最新版本的破解方法. 先到http://wingware.com/downloads/wingide下载最新版本的IDE. 安装之前,先修改时间到一个月前. 安装 安装之后然后获取试用版的 ...
- preg_replace数组的用法
$string = 'The quick brown fox jumped over the lazy dog.';$patterns = array();$patterns[2] = '/quick ...
- 没调出来 P2023
#include<iostream> #include<cstdio> #include<cstring> #define ll long long #define ...
- 网易UI自动化测试工具Airtest中导入air文件中的方法
最近看了一下网易的Airtest ,UI测试工具,写了一些后在导入其他air文件中的.py文件,卡了一下,现在博客中纪录一下导入其他air文件的方式: 在Airtest 测试工具中,导入其他air文件 ...
- python 线程池和锁
一.死锁现象与递归锁 锁:Lock线程安全,多线程操作时,内部会让所有线程排队处理.如:list/dict/Queue 线程不安全 + 人 => 排队处理. import thre ...
- .net core2.0 读取appsettings.json
一.在start.up中添加注入 二.使用
- 有关css的选择器优先级以及父子选择器
css,又称样式重叠表,如今的网页的样式基本是div+css写出来的,功能十分强大,要想在html文件中引入css文件需要在<head></head>标签内输入一行:<l ...
- poj3669 广搜
//好久没刷题了,生疏了. 题意分析: 题意理解为在一个二维的正向坐标轴上,一个点(流星)连同它的上下左右的四个点会在某一个时刻被破坏.一个人在原点,问她到达安全区的最小时间是多少. 代码思路: 从原 ...