久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL中Innodb Handler

217次閱讀
沒有評論

共計 14208 個字符,預計需要花費 36 分鐘才能閱讀完成。

這篇文章主要介紹“MySQL 中 Innodb Handler_read_* 參數分析”,在日常操作中,相信很多人在 MySQL 中 Innodb Handler_read_* 參數分析問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”MySQL 中 Innodb Handler_read_* 參數分析”的疑惑有所幫助!接下來,請跟著丸趣 TV 小編一起來學習吧!

一、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

內部表示:ha_read_key_count

Innodb 更改接口:ha_innobase::index_read

文檔解釋: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.

源碼函數解釋:Positions an index cursor to the index specified in the handle. Fetches the row if any.

作者解釋:這個函數是訪問索引的時候定位到值所在的位置用到的函數,因為必須要知道讀取索引的開始位置才能向下訪問。

2、Handler_read_next

內部表示:ha_read_next_count

Innodb 更改接口:ha_innobase::index_next_same ha_innobase::index_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.

源碼函數解釋:
index_next – Reads the next row from a cursor, which must have previously been positioned using index_read.
index_next_same – Reads the next row matching to the key value given as the parameter.

作者解釋:訪問索引的下一條數據封裝的 ha_innobase::general_fetch 函數,index_next_same 和 index_next 不同在于訪問的方式不一樣,比如范圍 range 查詢需要用到和索引全掃描也會用到 index_next,而 ref 訪問方式會使用 index_next_same

3、Handler_read_first

內部表示:ha_read_first_count

Innodb 更改接口:ha_innobase::index_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

源碼函數解釋:Positions a cursor on the first record in an index and reads the corresponding row to buf.

作者解釋:定位索引的第一條數據,實際上也是封裝的 ha_innobase::index_read  函數 (如全表掃描 / 全索引掃描調用)

4、Handler_read_rnd_next

內部表示:ha_read_rnd_next_count

Innodb 更改接口:ha_innobase::rnd_next

文檔解釋:The number of requests to read the next row in the data file. This value is high if you are doing a lot of table scans. Generally this suggests that your tables are not properly indexed or that your queries
are not written to take advantage of the indexes you have.

源碼函數解釋:Reads the next row in a table scan (also used to read the FIRST row in a table scan).

作者解釋:全表掃描訪問下一條數據,實際上也是封裝的 ha_innobase::general_fetch,在訪問之前會調用 ha_innobase::index_first

5、Handler_read_rnd

內部表示:ha_read_rnd_count

Innodb 更改接口:ha_innobase::rnd_pos

Memory 更改接口:ha_heap::rnd_pos

文檔解釋: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.

作者解釋:這個狀態值在我測試期間只發現對臨時表做排序的時候會用到,而且是 Memory 引擎的,具體只能按照文檔理解了。

6、其他

最后 2 個簡單說一下

Handler_read_prev
Innodb 接口為 ha_innobase::index_prev 訪問索引的上一條數據,實際上也是封裝的 ha_innobase::general_fetch 函數,用于 ORDER BY DESC 索引掃描避免排序,內部狀態值 ha_read_prev_count 增加。

Handler_read_last
Innodb 接口為 ha_innobase::index_last 訪問索引的最后一條數據作為定位,實際上也是封裝的 ha_innobase::index_read 函數,用于 ORDER BY DESC 索引掃描避免排序,內部狀態值 ha_read_last_count 增加。

三、常用查詢測試 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 
+----+-------------+-------+------------+-------+---------------+------+---------+------+-------+----------+-----------------------+| 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 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_* 參數分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注丸趣 TV 網站,丸趣 TV 小編會繼續努力為大家帶來更多實用的文章!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-24發表,共計14208字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 林口县| 梅州市| 绥德县| 扎鲁特旗| 平舆县| 宿州市| 沐川县| 奎屯市| 德安县| 新乡市| 高邮市| 富源县| 东海县| 本溪市| 尼玛县| 海伦市| 临沧市| 固始县| 大悟县| 翼城县| 东港市| 雷山县| 潜江市| 金山区| 南岸区| 密山市| 忻州市| 怀远县| 安义县| 柳江县| 竹北市| 惠东县| 房产| 无为县| 德钦县| 梅河口市| 万全县| 灵宝市| 电白县| 屏东县| 长治市|