本文共 15811 字,大约阅读时间需要 52 分钟。
本文为学习笔记,有误请指出。
内部表示如下:
{"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为主要学习对象进行解释。
index_next_same - Reads the next row matching to the key value given as the parameter.
is indexed
最后2个简单说一下
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)
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/nullPAGER 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。
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/nullPAGER set to 'cat >>/dev/null'mysql> select a from z1;56415 rows in set (4.57 sec)mysql> pagerDefault 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。
我这里因为是测试索引全是等于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/nullPAGER set to 'cat >>/dev/null'mysql> select * from z1 force index(a) where a=10;56414 rows in set (32.39 sec)mysql> pagerDefault 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增加扫描行数次数用于接下来的数据访问。
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/nullPAGER 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> pagerDefault 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增加扫描行数次数用于接下来的数据访问。
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/nullPAGER 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> pagerDefault 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增加为扫描的行数。
mysql> flush status;Query OK, 0 rows affected (0.05 sec)mysql> pager cat >> /dev/nullPAGER set to 'cat >> /dev/null'mysql> select * from z1 force index(a) order by a;56415 rows in set (27.39 sec)mysql> pagerDefault 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/nullPAGER set to 'cat >> /dev/null'mysql> select * from z1 force index(a) order by a desc;56415 rows in set (24.94 sec)mysql> pagerDefault 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的用途。
作者微信:
转载地址:http://avnqa.baihongyu.com/