Mysql 自定义HASH索引带来的巨大性能提升----[真相篇]
推倒重来
俗话说no zuo no die why you try,这时候我又忍不住zuo了,吭哧吭哧的把解决过程发上博客,向全世界宣布,哥又搞定个难题。
剧情的发展往往是看起来主角完全掌握了局势的情况下,会突然跳出来一个很牛的反面人物,然后搞得主角很惨,搞的过程中主角开始小宇宙爆发,然后逆袭。这次也不例外。踢场子的人该出现了


一顿狂侃之后,发现我原来牛逼的分析,完全经不起推敲。几个问题
1) 在未做HASH索引之前,为什么大表的ROWS那么大,相当于全表扫描
2) 既然SN是唯一索引,那么为什么关联查询的时候不能准确定位?
3) 在做了HASH索引之后,关联查询只是换了不同的判断字段,就能做到rows=1,这是为何?
在这里阐释一下通过索引是怎样做JOIN操作和索引定位数据的
在关系数据库里,常见的处理JOIN的方法有几种:NESTED LOOP,HASH JOIN,SORT MERGE JOIN,各种JOIN有什么差别WIKI上有详细的介绍。MYSQL实现的是NESTED LOOP,俗称嵌套循环。
结合前面的查询来看,JOIN的关联字段是FDEVICE和FSN,查询的过程是这样的
FOR FDEVICE IN A:
FOR FSN IN B:
IF A.FDEVICE=B.FSN:
Store result into record buffer
Send result
嵌套循环就是这么实现的。
在IF A.FDEVICE=B.FSN:这一步,对B表数据进行比较时,B的FSH上有索引,先通过索引查找,得到主键ID,然后根据主键ID获取整行记录的具体值。
在这个案例里,B的FSN是唯一值,A的FDEVICE在B表里,要么不存在,要么只有一条记录与之匹配,不会有第三种情况发生。
在未做自定义hash索引之前的SQL,应该就是这个执行过程才对,hash一次后,再在hash 字段做个索引,其实只是换了个实现途径,并没有解释为什么之前的方法为什么会全表扫描,潜伏在表象下的真相并不如此。
回到事件的原点,为什么最开始的那个SQL的执行计划里,ROWS等于全表,而走自定义hash索引后的rows=1?通过对索引原理的分析,它只要是用了索引,rows必然是1,如果没有用到索引,那么key这一列又必然是NULL,正是这个矛盾,从一开始就把我引向歧途,误认为是索引本身的问题,然后想当然的弄了个hash索引,然后误打误撞把问题解决。
意外发现
首先要把一切不可能的事实都排除,那其余的,不管多么离奇,多么难以置信,也必然是无可辩驳的事实 夏洛克.福尔摩斯
在这个案例里,不可能的事实就是,嵌套循环的执行过程不会变,索引查找数据的过程不会变。那么还剩下什么?
1) 看到的ROWS=490W是假象 2)看到的key=sn是假象
从执行效率来看,ROWS=490W是真的,要么不会这么慢,那么KEY=SN是假的就有可能,看起来用到了索引,事实上索引完全没有起作用。
再次把视线集中到两个关联查询的表结构上,发现一个很不起眼的异常现象:`sn` varchar(20) CHARACTER SET utf8 。这个字段的字符集是utf8的,而与之关联的字段的字符集是utf8mb4的,两个不同的字段比较,是不是会引起索引失效?
很快实验结果就出来了,而这次,才是事件背后的真相。

当两个关联字段的字符集相同时,索引运行如预期。
当我只有一个锤子时,很自然的把任何问题都看成钉子,先入为主的思维使一些简单而重要的细节被忽略,而这些线索能指引我们找出事情的真相。走完一圈弯路蓦然回首,其实那个苦苦寻觅的完美世界就在眼前,只是我们被偏见和愚昧蒙蔽了双眼。
Mysql 自定义HASH索引带来的巨大性能提升----[真相篇]的更多相关文章
- Mysql 自定义HASH索引带来的巨大性能提升----[挖坑篇]
有这样一个业务场景,需要在2个表里比较存在于A表,不存在于B表的数据.表结构如下: T_SETTINGS_BACKUP | CREATE TABLE `T_SETTINGS_BACKUP` ( `FI ...
- Mysql 自定义HASH索引带来的巨大性能提升
有这样一个业务场景,需要在2个表里比较存在于A表,不存在于B表的数据.表结构如下: T_SETTINGS_BACKUP | CREATE TABLE `T_SETTINGS_BACKUP` ( `FI ...
- MySQL 8.0 —— CATS事务调度算法的性能提升
原文地址:https://mysqlserverteam.com/contention-aware-transaction-scheduling-arriving-in-innodb-to-boost ...
- SQL优化系列(三)- 用最少的索引获得最大的性能提升
从全局出发优化索引 对于高负载的数据库,如何创建最少的索引,让数据库的整体性能提高呢?例如,对于100 条SQL语句,如何创建最佳的5条索引? SQL自动优化工具SQL Tuning Expert P ...
- MySQL系列(六)--索引优化
在进行数据库查询的时候,索引是非常重要的,当然前提是达到一定的数据量.索引就像字典一样,通过偏旁部首来快速定位,而不是一页页 的慢慢找. 索引依赖存储引擎层实现,所以支持的索引类型和存储引擎相关,同一 ...
- InnoDB关键特性之自适应hash索引
一.索引的资源消耗分析 1.索引三大特点 1.小:只在一个到多个列建立索引 2.有序:可以快速定位终点 3.有棵树:可以定位起点,树高一般小于等于3 2.索引的资源消耗点 1.树的高度,顺序访问索引的 ...
- 数据库索引------B-Tree 索引和 Hash 索引的对比
对于 B-tree 和 hash 数据结构的理解能够有助于预测不同存储引擎下使用不同索引的查询性能的差异,尤其是那些允许你选择 B-tree 或者 hash 索引的内存存储引擎. B-Tree 索引的 ...
- B-Tree 索引和 Hash 索引的对照
对于 B-tree 和 hash 数据结构的理解可以有助于预測不同存储引擎下使用不同索引的查询性能的差异.尤其是那些同意你选择 B-tree 或者 hash 索引的内存存储引擎. B-Tree 索引的 ...
- Innodb关键特性之自适用Hash索引
一.索引的资源消耗分析 1.索引三大特点 1.小:只在一个到多个列建立索引 2.有序:可以快速定位终点 3.有棵树:可以定位起点,树高一般小于等于3 2.索引的资源消耗点 1.树的高度,顺序访问索引的 ...
随机推荐
- python抓取数据 常见反爬虫 情况
1.报文头信息: User-Agent Accept-Language 防盗链 上referer 随机生成不同的User-Agent构造报头 2.加抓取等待时间 每抓取一页都让它随机休息几秒,加入此 ...
- java 多线程—— 线程让步
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- JDE Develop Server分别安装DV PY PD后WEBSERVER问题
一般安装时一次性安装完DV\PY\PD环境后,再安装WEBSERVER时只需要修改一次配置文件即可,但如果先安装顺序如下: DV->WEBSERVER->PY 此时,配置程序被初始化,必须 ...
- Java:Collection List Set
Java:集合 常见集合:List Set List 特点:元素是有序的,而且元素可以重复,因为该集合体系有索引. 常见的三个子类:ArrayList.LinkedList.Verctor List集 ...
- iOS_autoLayout_Masonry
概述 Masonry是一个轻量级的布局框架与更好的包装AutoLayout语法. Masonry有它自己的布局方式,描述NSLayoutConstraints使布局代码更简洁易读. ...
- iOS开发Swift篇—(三)字符串和数据类型
iOS开发Swift篇—(三)字符串和数据类型 一.字符串 字符串是String类型的数据,用双引号""包住文字内容 let website = "http://www ...
- 如何使用 Quagga BGP(边界网关协议)路由器来过滤 BGP 路由
在之前的文章中,我们介绍了如何使用 Quagga 将 CentOS 服务器变成一个 BGP 路由器,也介绍了 BGP 对等体和前缀交换设置.在本教程中,我们将重点放在如何使用前缀列表prefix-li ...
- Jenkins快速上手
一.Jenkins下载安装 1.到官网下载jenkins.war包:http://jenkins-ci.org/ 2.安装方法有两种: a) 把下载下来的jenkins.war包放到文件夹下,如C:\ ...
- androidd 程序默认安装位置和数据存储位置(公用和私用)
默认安装位置: android App 安装到外置SD卡中,缓解手机内置内存的压力: <manifest xmlns:android="http://schemas.android.c ...
- MS Sql server 2008 学习笔记
数据库中常用的概念 Sql本身是一个服务器,没有界面,Management Studio 只是一个SQL Server管理工具而已,不是服务器. Sql server 在管理工具下面的服务SQL S ...