MySQL中存在Handler的用法。Handler一般是用于控制流程的系统行为,普遍分为rule handler(规则处理程序)与action handler(操作处理程序)。
MySQL里action handler,可以在流程节点不同的状态中做需要的操作。在源码中,虽然开放了很多handler接口,提供对表存储引擎接口的直接访问。但目前只可用于InnoDB和MyISAM表。

语法如下:
HANDLER tbl_name OPEN [ [AS] alias]
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name CLOSE
- 通过OPEN 表, 也可以使用别名alias。
- 通过指定索引, FIRST,NEXT,PREV,LAST 方式获取。
- 指定条件,FIRST,NEXT,LIMIT方式获取。
- 如果没有LIMIT子句,所有形式的HANDLER。。。READ获取单行。
- 处理完之后,需要CLOSE关闭用HANDLER打开的表。
实例:
MySQL> CREATE TABLE `tb_handler` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(10) ,
`age` int DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_nm` (`name`)
) ENGINE=InnoDB;
MySQL> INSERT INTO tb_handler(name,age) values('C',11),('K',14),('B',12),('W',16);
MySQL> SELECT * FROM tb_handler;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | C | 11 |
| 2 | K | 14 |
| 3 | A | 13 |
| 4 | B | 12 |
| 5 | W | 16 |
+----+------+------+
5 rows in set (0.00 sec)
1.查看数据
mysql> handler tb_handler open;
Query OK, 0 rows affected (0.00 sec)
mysql> handler tb_handler READ first;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | C | 11 |
+----+------+------+
1 row in set (0.00 sec)
mysql> handler tb_handler READ NEXT;
+----+------+------+
| id | name | age |
+----+------+------+
| 2 | K | 14 |
+----+------+------+
1 row in set (0.00 sec)
mysql> handler tb_handler READ FIRST LIMIT 2;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | C | 11 |
| 2 | K | 14 |
+----+------+------+
2 rows in set (0.00 sec)
mysql> handler tb_handler READ NEXT where id=4;;
+----+------+------+
| id | name | age |
+----+------+------+
| 4 | W | 16 |
+----+------+------+
1 row in set (0.00 sec)
mysql> HANDLER tb_handler CLOSE;
2.索引引用
以 tb_handler 中的 索引名idx_nm 抽取数据。
mysql> handler tb_handler open;
Query OK, 0 rows affected (0.00 sec)
mysql> handler tb_handler READ `idx_nm` first;
+----+------+------+
| id | name | age |
+----+------+------+
| 3 | B | 12 |
+----+------+------+
1 row in set (0.00 sec)
mysql> HANDLER tb_handler CLOSE;
3.存储过程
存储过程中通过handler处理程序语句后执行的操作。
DECLARE handler_action HANDLER
FOR condition_value [, condition_value] ...
statement
handler_action: {
CONTINUE
| EXIT
| UNDO
}
condition_value: {
mysql_error_code
| SQLSTATE [VALUE] sqlstate_value
| condition_name
| SQLWARNING
| NOT FOUND
| SQLEXCEPTION
}
CONTINUE继续:继续执行当前程序。
EXIT退出:BEGIN的执行终止。。。END复合语句,其中声明了处理程序。
UNDO:不支持
存储过程中handler操作:
mysql> CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter //
mysql> CREATE PROCEDURE handlerdemo ()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
SET @x = 1;
INSERT INTO test.t VALUES (1);
SET @x = 2;
INSERT INTO test.t VALUES (1);
SET @x = 3;
END;
//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL handlerdemo()//
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @x//
+------+
| @x |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
4.状态值
表的表锁或锁请求数,通过In_use方式查看(HANDLER减少关闭)。
mysql> show open tables where in_use >=1;
+----------+------------+--------+-------------+
| Database | Table | In_use | Name_locked |
+----------+------------+--------+-------------+
| db1 | tb_handler | 1 | 0 |
+----------+------------+--------+-------------+
1 row in set (0.00 sec)
STATUS状态值本身就提供handler指标。
mysql> show global status like '%handler%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Handler_commit | 1277 |
| Handler_delete | 8 |
| Handler_discover | 0 |
| Handler_external_lock | 9011 |
| Handler_mrr_init | 0 |
| Handler_prepare | 0 |
| Handler_read_first | 51 |
| Handler_read_key | 2623 |
| Handler_read_last | 0 |
| Handler_read_next | 5576 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 8165 |
| Handler_rollback | 2 |
| Handler_savepoint | 0 |
| Handler_savepoint_rollback | 0 |
| Handler_update | 332 |
| Handler_write | 404 |
+----------------------------+-------+
18 rows in set (0.00 sec)
总结
handler更趋向于程序中的逐步处理方式,对于MySQL数据库来说属于属于存储过程类似的功能,所以谨慎使用。按照官方说明,使用handler比select更快:
1.指定的存储引擎处理程序对象已分配给handler。。。打开。该对象被重复用于该表的后续HANDLER语句;不需要对每一个进行重新初始化。
2.所涉及的解析较少。
3.没有优化器或查询检查开销。
4.处理程序接口不必提供一致的数据外观(例如,允许脏读取)
5.HANDLER使移植到使用低级ISAM类接口的MySQL应用程序变得更容易。
参考
https://dev.mysql.com/doc/dev/mysql-server/latest/classhandler.html
https://dev.mysql.com/doc/refman/8.0/en/handler.html
https://dev.mysql.com/doc/refman/8.0/en/declare-handler.html




