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

 更新时间:2016年07月17日 00:19:18   投稿:mdxy-dxy  
这篇文章主要介绍了MYSQL神秘的HANDLER命令与实现方法,需要的朋友可以参考下

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君每次写查询时都要打开官方的命令对照表……

相关文章

  • 关于sql count(列名)、count(常量)、count(*)之间的区别

    关于sql count(列名)、count(常量)、count(*)之间的区别

    这篇文章主要介绍了关于sql count(列名)、count(常量)、count(*)之间的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Mysql默认设置的危险性分析

    Mysql默认设置的危险性分析

    一.mysql默认的授权表二.缺乏日志能力 三.my.ini文件泄露口令 四.服务默认被绑定全部的网络接口上 五.默认安装路径下的mysql目录权限
    2008-09-09
  • MySQL 中常见的几种高可用架构部署方案解析

    MySQL 中常见的几种高可用架构部署方案解析

    MySQL Replication 是官方提供的主从同步方案,用于将一个 MySQL 的实例同步到另一个实例中,这篇文章主要介绍了MySQL 中常见的几种高可用架构部署方案,需要的朋友可以参考下
    2023-04-04
  • MySQL表的增删查改及聚合函数/group by子句的使用方法举例

    MySQL表的增删查改及聚合函数/group by子句的使用方法举例

    这篇文章主要给大家介绍了关于MySQL表的增删查改及聚合函数/group by子句的使用方法,在MySQL中可以使用聚合函数与GROUP BY语句可以对数据进行分组并进行聚合计算,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • mysql 开启慢查询 如何打开mysql的慢查询日志记录

    mysql 开启慢查询 如何打开mysql的慢查询日志记录

    mysql慢查询日志对于跟踪有问题的查询非常有用,可以分析出当前程序里有很耗费资源的sql语句,那如何打开mysql的慢查询日志记录呢,接下来将详细为您介绍
    2012-11-11
  • MySQL中主键为0与主键自排约束的关系详解(细节)

    MySQL中主键为0与主键自排约束的关系详解(细节)

    这篇文章主要给大家介绍了关于MySQL中主键为0与主键自排约束的关系的相关资料,主要介绍的是其中的一些非常细的细节,对大家学习或者使用mysql具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-05-05
  • MySQL OOM 系统二 OOM Killer

    MySQL OOM 系统二 OOM Killer

    前面一节重点分享了Linux的内存分配策略,基于上述的分配策略,为了规避超售的风险,Linux采了一种OOM Killer的机制,即系统可用内存(包括Swap)即将使用完之前,选择性的Kill掉一些进程以求释放一些内存
    2016-07-07
  • Mysql5.7如何修改root密码

    Mysql5.7如何修改root密码

    mysql修改管理员root的密码是个很常见的问题了,网上也有很多的教程,然而新版的MYSQL5.7却能使用之前的教程,小编经过一番摸索,才找到了修改办法,这里分享给大家。
    2016-01-01
  • MySQL 空间碎片的查看与回收

    MySQL 空间碎片的查看与回收

    ySQL数据库在运行过程中可能会出现空间碎片的问题,本文就来介绍一下MySQL 空间碎片的查看与回收 ,具有一定的参考价值,感兴趣的可以了解一下
    2025-02-02
  • MySQL更新删除操作update和delete使用详解(小白慎用)

    MySQL更新删除操作update和delete使用详解(小白慎用)

    这篇文章主要为大家介绍了MySQL的更新删除操作update和delete使用但是一定要慎用啊,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05

最新评论