기술 공유 | InnoDB Handlerread_* 변수 해석
글 말미에는 그가 저술한'마이SQL 주종원리 깊이 이해32강'이 있고, 마이SQL 주종, GTID 관련 기술 지식을 깊이 있게 이해한다.
원본 버전:percona 5.7.14
본문은 학습 기록이므로 오류가 있을 수 있으니 양해해 주십시오.
이 문서는 PC에서 보는 것이 더욱 효과적일 것을 권장합니다.
1,Handlerread_* 값의 본질
내부 표현은 다음과 같습니다.
{"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를 주요 학습 대상으로 삼아 해석할 것이다.
2. 각 값의 해석
1. Handler_read_key
2. Handler_read_next
querying an index column with a range constraint or if you are doing an index scan.
3. Handler_read_first
server is doing a lot of full index scans; for example, SELECT col1 FROM foo, assuming that col1is indexed
are not written to take advantage of the indexes you have.
5. Handler_read_rnd
6.기타
마지막 두 개. 짧게 말해주세요.
Innodb 인터페이스는 ha 입니다.innobase::index_prev 색인에 접근한 이전 데이터, 실제로도 봉인된hainnobase::general_fetch 함수, ORDER By DESC 인덱스 검색을 위한 정렬 방지, 내부 상태 값haread_prev_count 증가.
Innodb 인터페이스는 ha 입니다.innobase::index_last 접근 인덱스의 마지막 데이터를 포지셔닝으로 하고 실제로는 봉인된hainnobase::index_ORDER BY DESC 색인 검색을 위한 정렬 방지, 내부 상태 값 haread_last_count 증가.
3. 상용 조회 테스트
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회 추가,Handlerread_키 1회 증가,Handlerread_rnd_next에서 스캔 줄 수를 증가합니다.저희가 앞에서 말했잖아요. 하 때문에.innobase::index_first도 봉인된hainnobase::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회 추가,Handlerread_키 1회 증가,Handlerread_다음 줄을 연속으로 접근하는 데 사용할 스캔 줄 수를 추가합니다.저희가 앞에서 말했잖아요. 하 때문에.innobase::index_first도 봉인된hainnobase::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_키 1회 추가 첫 번째 포지셔닝에 사용됨,Handlerread_다음 데이터 접근에 사용할 스캔 줄 수를 늘립니다.
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_키 1회 추가 첫 번째 포지셔닝에 사용됨,Handlerread_다음 데이터 접근에 사용할 스캔 줄 수를 늘립니다.
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 전체 테이블 스캔 포지셔닝의 시작으로 한 번 추가합니다. 다음handlerread_rnd_next 모든 기록을 스캔합니다. 매번 스캔할 때마다 z10표에서 색인 aidx 포지셔닝 Handlerread_키 1회 추가, 다음 색인 a 진행idx 데이터 검색Handlerread_next가 스캔하는 줄 수로 증가했습니다.
7. 인덱스는 정렬의 정방향과 반전을 피한다
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)
너무 설명하지 않아도 Handlerread_last 및 Handlerread_prev의 용도.
4. 총결산
순서대로 방문한 기록은 실제로ha 를 호출합니다innobase::general_fetch 함수, 다른 기능 innodbthread_concurrency 매개 변수의 기능은 그 안에서 실현됩니다. 다음에 다시 이야기합시다.
5. 참고 창고 프레임
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)
:
#0 row_search_mvcc (buf=0x7fff2ccc9380 "\377", mode=PAGE_CUR_G, prebuilt=0x7fff2cd4bb40, match_mode=0, direction=0)
at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/row/row0sel.cc:4479
#1 0x00000000019b3051 in ha_innobase::index_read (this=0x7fff2cd32480, buf=0x7fff2ccc9380 "\377", key_ptr=0x0, key_len=0, find_flag=HA_READ_AFTER_KEY)
at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/handler/ha_innodb.cc:9104
#2 0x00000000019b4374 in ha_innobase::index_first (this=0x7fff2cd32480, buf=0x7fff2ccc9380 "\377")
at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/handler/ha_innodb.cc:9551
#3 0x00000000019b462c in ha_innobase::rnd_next (this=0x7fff2cd32480, buf=0x7fff2ccc9380 "\377")
at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/handler/ha_innodb.cc:9656
#4 0x0000000000f66fa2 in handler::ha_rnd_next (this=0x7fff2cd32480, buf=0x7fff2ccc9380 "\377") at /root/mysql5.7.14/percona-server-5.7.14-7/sql/handler.cc:3099
#5 0x00000000014c61b6 in rr_sequential (info=0x7fff2c0026a0) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/records.cc:520
#6 0x000000000155f2a4 in join_init_read_record (tab=0x7fff2c002650) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_executor.cc:2481
#7 0x000000000155c381 in sub_select (join=0x7fff2c001f70, qep_tab=0x7fff2c002650, end_of_records=false)
at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_executor.cc:1271
#8 0x000000000155bd
마지막으로 고붕의 칼럼인'마이SQL 주종원리를 깊이 이해하다 32강'을 추천하며, 마이SQL 주종원리를 철저히 이해하고자 하는 친구들을 놓치지 말아야 한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
SQLite의 query로 망설임이것은 내가 처음 안드로이드 응용 프로그램 개발에서 망설이고, 그 후 해결 된 방법을 비망록으로 철자하고 있습니다. java에서 SQLite를 이용한 애플리케이션을 작성하는 동안 EditText에 입력된 item이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.