MYSQL神秘的HANDLER命令与实现方法

所属分类: 数据库 / Mysql 阅读数: 1374
收藏 0 赞 0 分享

MySQL“自古以来”都有一个神秘的HANDLER命令,而此命令非SQL标准语法,可以降低优化器对于SQL语句的解析与优化开销,从而提升查询性能。看到这里,可能有小伙伴不淡定了,这么好的东西为啥没广泛使用呢?这不是与几年前很夯的handlersocket插件类似吗?

那么,我们先来看看Handler语法说明:

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

首先从语法上看,HANDLER可以通过指定的索引去访问数据。但此语法并不支持DML操作。此外,由于减少了SQL解析,Handler命令的性能真的非常不错,根据Inside君的简单主键测试,Handler命令比SQL要快40%~45%。测试脚本如下:

SET @id=FLOOR(RAND()*1000000);
HANDLER sbtest.sbtest1 OPEN AS c;
HANDLER C READ `PRIMARY` = (@id);
HANDLER C CLOSE;

在Inside君的24C的测试服务器上,64线程主键查询跑到了近37W QPS,还是非常令人印象深刻的。对比SQL的SELECT查询,整体测试结果如下图所示:

命令HANDLER的主要实现在源码sql_handler.h、sql_handler.cc,设个断点就能观察到具体的流程。MySQL上层及InnoDB存储引擎层主要实现函数入口为:

复制代码 代码如下:

Sql_cmd_handler_open::execute
Sql_cmd_handler_read::execute
Sql_cmd_handler_close::execute
ha_innobase::init_table_handle_for_HANDLER
ha_partition::init_table_handle_for_HANDLER()(7版本支持HANDLER操作分区表)

既然性能不错,为什么在生产环境中并不见到命令HANDLER的使用呢?主要是因为HANDLER命令存在以下几个主要问题:

非一致性读取???
返回聚集索引中的所有列(即使是二级索引访问),而不能返回某个具体列
二级索引不使用LIMIT关键字,只能返回1行记录
知道命令HANDLER的同学,可能会认为HANDLER读取存在脏读问题。因为MySQL官方文档对于HANDLER读取的说明就是这么说的:

The handler interface does not have to provide a consistent look of the data (for example, dirty reads are permitted), so the storage engine can use optimizations that SELECT does not normally permit.
然而需要特别注意的是,MySQL文档中准确的说法是可以允许提供不一致的读取。但InnoDB存储引擎的HANDLER实现是支持一致性读取的,Inside君亲测的确不存在脏读问题。当然,源码说明一切,可以发现在函数init_table_handle_for_HANDLER会对READVIEW进行分配,而注释也说明了这点:

/* We let HANDLER always to do the reads as consistent reads, even
if the trx isolation level would have been specified as SERIALIZABLE */
m_prebuilt->select_lock_type = LOCK_NONE;
m_prebuilt->stored_select_lock_type = LOCK_NONE;

貌似用HANDLER命令来做主键的查询是不错的,减少了SQL解析器的开销,性能提升杠杠的。但为此,应用要付出巨大的改动,而SQL最大的优势就在于标准化。相信这也是目前NoSQL数据库遇到的最大的一个问题。比如MongoDB,Inside君每次写查询时都要打开官方的命令对照表……

更多精彩内容其他人还在看

mysql数据表的基本操作之表结构操作,字段操作实例分析

这篇文章主要介绍了mysql数据表的基本操作之表结构操作,字段操作,结合实例形式分析了mysql表结构操作,字段操作常见增删改查实现技巧与操作注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

mysql学习笔记之完整的select语句用法实例详解

这篇文章主要介绍了mysql学习笔记之完整的select语句用法,结合实例形式详细分析了mysql select语句各种常见参数、使用方法及操作注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

MySQL5.6 GTID模式下同步复制报错不能跳过的解决方法

搭建虚拟机centos6.0, mysql5.6.10主从复制,死活不同步,搞了一整天找到这篇文章终于OK了,特分享一下,需要的朋友可以参考下
收藏 0 赞 0 分享

MySQL开启慢查询方法及实例

这篇文章主要介绍了MySQL开启慢查询方法及实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享

简单了解MYSQL数据库优化阶段

这篇文章主要介绍了简单了解MYSQL数据库优化阶段,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Windows下MySQL主从复制的配置方法

MySQL主从复制允许将来自一个数据库(主数据库)的数据复制到一个或多个数据库(从数据库),主数据库一般是实时的业务数据写入和更新操作,从数据库常用的读取为主
收藏 0 赞 0 分享

Mysql数据库设计三范式实例解析

这篇文章主要介绍了Mysql数据库设计三范式实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享

mysql数据类型和字段属性原理与用法详解

这篇文章主要介绍了mysql数据类型和字段属性,结合实例形式分析了mysql数据类型和字段属性基本概念、原理、分类、用法及操作注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

mysql连接查询、联合查询、子查询原理与用法实例详解

这篇文章主要介绍了mysql连接查询、联合查询、子查询原理与用法,结合实例形式详细分析了mysql连接查询、联合查询、子查询的基本概念、功能、原理、用法及操作注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

Window下如何恢复被删除的Mysql8.0.17 Root账户及密码

这篇文章主要介绍了Window下如何恢复被删除的Mysql8.0.17 Root账户及密码,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多