文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MySQL中Innodb Handler_read_*参数分析

2024-04-02 19:55

关注

这篇文章主要介绍“MySQL中Innodb Handler_read_*参数分析”,在日常操作中,相信很多人在MySQL中Innodb Handler_read_*参数分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL中Innodb Handler_read_*参数分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一、Handler_read_*值的实质

内部表示如下:

  {"Handler_read_first",       (char*) offsetof(STATUS_VAR, ha_read_first_count),     SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
  {"Handler_read_key",         (char*) offsetof(STATUS_VAR, ha_read_key_count),       SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
  {"Handler_read_last",        (char*) offsetof(STATUS_VAR, ha_read_last_count),      SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
  {"Handler_read_next",        (char*) offsetof(STATUS_VAR, ha_read_next_count),      SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
  {"Handler_read_prev",        (char*) offsetof(STATUS_VAR, ha_read_prev_count),      SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
  {"Handler_read_rnd",         (char*) offsetof(STATUS_VAR, ha_read_rnd_count),       SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},
  {"Handler_read_rnd_next",    (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count),  SHOW_LONGLONG_STATUS,    SHOW_SCOPE_ALL},

实际上这些变量都是MySQL层定义出来的,因为MySQL可以包含多个存储引擎。因此这些值如何增加需要在引擎层的接口中自行实现,也就是说各个引擎都有自己的实现,在MySQL层进行汇总,因此这些值不是某个引擎特有的,打个比方如果有Innodb和MyISAM引擎,那么这些值是两个引擎的总和。本文将以Innodb为主要学习对象进行解释。

二、各个值的解释

1、Handler_read_key
2、Handler_read_next
3、Handler_read_first
4、Handler_read_rnd_next
5、Handler_read_rnd
6、其他

最后2个简单说一下

三、常用查询测试

1、测试用例
mysql> show create table z1;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                              |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------+
| z1    | CREATE TABLE `z1` (  `a` int(11) DEFAULT NULL,  `name` varchar(20) DEFAULT NULL,
  KEY `a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------+1 row in set (0.00 sec)
mysql> show create table z10;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                   |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------+
| z10   | CREATE TABLE `z10` (  `a` int(11) DEFAULT NULL,  `name` varchar(20) DEFAULT NULL,
  KEY `a_idx` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------+1 row in set (0.00 sec)
mysql> select count(*) from z1;
+----------+
| count(*) |
+----------+
|    56415 |
+----------+1 row in set (5.27 sec)
mysql> select count(*) from z10;
+----------+
| count(*) |
+----------+
|       10 |
+----------+1 row in set (0.00 sec)
2、全表扫描
mysql> desc select * from z1;
+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------+
|  1 | SIMPLE      | z1    | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 56650 |   100.00 | NULL  |+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------+1 row in set, 1 warning (0.00 sec)
mysql> pager cat >>/dev/null
PAGER set to 'cat >>/dev/null'mysql> flush status;
Query OK, 0 rows affected (0.10 sec)
mysql> select * from z1;56415 rows in set (4.05 sec)
mysql> pager;
Default pager wasn't set, using stdout.
mysql> show 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 | 56416 |
+-----------------------+-------+
7 rows in set (0.01 sec)

Handler_read_first增加1次用于初次定位,Handler_read_key增加1次,Handler_read_rnd_next增加扫描行数。我们前面说过因为ha_innobase::index_first也是封装的ha_innobase::index_read因此都需要+1。

3、全索引扫描
mysql> desc select a from z1;
+----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-------------+| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | z1    | NULL       | index | NULL          | a    | 5       | NULL | 56650 |   100.00 | Using index |+----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-------------+1 row in set, 1 warning (0.00 sec)
mysql> flush status;
Query OK, 0 rows affected (0.12 sec)
mysql> pager cat >>/dev/null
PAGER set to 'cat >>/dev/null'mysql> select a from z1;56415 rows in set (4.57 sec)
mysql> pager
Default pager wasn't set, using stdout.
mysql> show status like 'Handler_read%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Handler_read_first    | 1     |
| Handler_read_key      | 1     |
| Handler_read_last     | 0     |
| Handler_read_next     | 56415 |
| Handler_read_prev     | 0     |
| Handler_read_rnd      | 0     |
| Handler_read_rnd_next | 0     |
+-----------------------+-------+
7 rows in set (0.01 sec)

Handler_read_first增加1次用于初次定位,Handler_read_key增加1次,Handler_read_next增加扫描行数用于连续访问接下来的行。我们前面说过因为ha_innobase::index_first也是封装的ha_innobase::index_read因此都需要+1。

4、索引ref访问

我这里因为是测试索引全是等于10的加上了force index

mysql>  desc select  * from z1 force index(a) where a=10;
+----+-------------+-------+------------+------+---------------+------+---------+-------+-------+----------+-------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref   | rows  | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+-------+-------+----------+-------+
|  1 | SIMPLE      | z1    | NULL       | ref  | a             | a    | 5       | const | 28325 |   100.00 | NULL  |+----+-------------+-------+------------+------+---------------+------+---------+-------+-------+----------+-------+1 row in set, 1 warning (0.01 sec)
mysql> flush status;
Query OK, 0 rows affected (0.13 sec)
mysql> pager cat >>/dev/null
PAGER set to 'cat >>/dev/null'mysql> select  * from z1 force index(a) where a=10;56414 rows in set (32.39 sec)
mysql> pager
Default pager wasn't set, using stdout.
mysql> show status like 'Handler_read%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Handler_read_first    | 0     |
| Handler_read_key      | 1     |
| Handler_read_last     | 0     |
| Handler_read_next     | 56414 |
| Handler_read_prev     | 0     |
| Handler_read_rnd      | 0     |
| Handler_read_rnd_next | 0     |
+-----------------------+-------+
7 rows in set (0.06 sec)

Handler_read_key增加1次这是用于初次定位,Handler_read_next增加扫描行数次数用于接下来的数据访问。

5、索引range访问
mysql> desc select  * from z1 force index(a) where a>9 and a<12;
+----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-----------------------+| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref  | rows  | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-----------------------+
|  1 | SIMPLE      | z1    | NULL       | range | a             | a    | 5       | NULL | 28325 |   100.00 | Using index condition |+----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-----------------------+1 row in set, 1 warning (0.00 sec)
mysql>  pager cat >>/dev/null
PAGER set to 'cat >>/dev/null'mysql> select  * from z1 force index(a) where a>9 and a<12;56414 rows in set (47.54 sec)
mysql> show status like 'Handler_read%';7 rows in set (0.03 sec)
mysql>  pager
Default pager wasn't set, using stdout.
mysql> show status like 'Handler_read%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Handler_read_first    | 0     |
| Handler_read_key      | 1     |
| Handler_read_last     | 0     |
| Handler_read_next     | 56414 |
| Handler_read_prev     | 0     |
| Handler_read_rnd      | 0     |
| Handler_read_rnd_next | 0     |
+-----------------------+-------+
7 rows in set (0.02 sec)

Handler_read_key增加1次这是用于初次定位,Handler_read_next增加扫描行数次数用于接下来的数据访问。

6、被驱动表带索引访问
mysql> desc select * from z1 STRAIGHT_JOIN z10 force index(a_idx) on z1.a=z10.a;
+----+-------------+-------+------------+------+---------------+-------+---------+-----------+-------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key   | key_len | ref       | rows  | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+-------+---------+-----------+-------+----------+-------------+
|  1 | SIMPLE      | z1    | NULL       | ALL  | a             | NULL  | NULL    | NULL      | 56650 |   100.00 | Using where ||  1 | SIMPLE      | z10   | NULL       | ref  | a_idx         | a_idx | 5       | test.z1.a |    10 |   100.00 | NULL        |
+----+-------------+-------+------------+------+---------------+-------+---------+-----------+-------+----------+-------------+
2 rows in set, 1 warning (0.01 sec)
mysql> flush status;
Query OK, 0 rows affected (0.47 sec)
mysql> pager cat >> /dev/null
PAGER set to 'cat >> /dev/null'
mysql>  select * from z1 STRAIGHT_JOIN z10 force index(a_idx) on z1.a=z10.a;
112828 rows in set (1 min 21.21 sec)
mysql> pager
Default pager wasn't set, using stdout.
mysql>  show status like 'Handler_read%';
+-----------------------+--------+
| Variable_name         | Value  |+-----------------------+--------+| Handler_read_first    | 1      |
| Handler_read_key      | 56416  || Handler_read_last     | 0      |
| Handler_read_next     | 112828 || Handler_read_prev     | 0      |
| Handler_read_rnd      | 0      || Handler_read_rnd_next | 56416  |
+-----------------------+--------+
7 rows in set (0.00 sec)

Handler_read_first 增加一次作为驱动表z1全表扫描定位的开始,接下来Handler_read_rnd_next扫描全部记录,每次扫描一次在z10表通过索引a_idx定位一次Handler_read_key增加1次,然后接下来进行索引a_idx进行数据查找Handler_read_next增加为扫描的行数。

6、索引避免排序正向和反向
mysql>  flush status;
Query OK, 0 rows affected (0.05 sec)
mysql> pager cat >> /dev/null
PAGER set to 'cat >> /dev/null'mysql> select * from z1 force index(a) order by a;56415 rows in set (27.39 sec)
mysql> pager
Default pager wasn't set, using stdout.
mysql> show status like 'Handler_read%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Handler_read_first    | 1     |
| Handler_read_key      | 1     |
| Handler_read_last     | 0     |
| Handler_read_next     | 56415 |
| Handler_read_prev     | 0     |
| Handler_read_rnd      | 0     |
| Handler_read_rnd_next | 0     |
+-----------------------+-------+
7 rows in set (0.01 sec)
mysql> flush status;
Query OK, 0 rows affected (0.10 sec)
mysql> desc  select * from z1 force index(a) order by a desc;
+----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref  | rows  | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-------+
|  1 | SIMPLE      | z1    | NULL       | index | NULL          | a    | 5       | NULL | 56650 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> pager cat >> /dev/null
PAGER set to 'cat >> /dev/null'
mysql>  select * from z1 force index(a) order by a desc;
56415 rows in set (24.94 sec)
mysql> pager
Default pager wasn't set, using stdout.
mysql>  show 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     | 56415 || Handler_read_rnd      | 0     |
| Handler_read_rnd_next | 0     |+-----------------------+-------+7 rows in set (0.01 sec)

不用过多解释,可以看到Handler_read_last 和Handler_read_prev的用途。

到此,关于“MySQL中Innodb Handler_read_*参数分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯