暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

MySQL Handler解析

原创 CuiHulong 2023-08-10
1190

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

语法如下:

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

最后修改时间:2023-08-11 10:28:24
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论