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.树的高度,顺序访问索引的 ...
随机推荐
- JavaScipt的秘密花园
对象使用和属性 JavaScript 中所有变量都可以当作对象使用,除了两个例外 null 和undefined. false.toString(); // 'false'[1, 2, 3].toSt ...
- springmvc__SimpleUrlHandlerMapping(对访问地址进行加工,以键值对的形式)
1.配置web.xml(这里配置url-pattern为/) <!-- 编码过滤器 --> <filter> <filter-name>characterEncod ...
- Python高效编程的19个技巧
初识Python语言,觉得python满足了我上学时候对编程语言的所有要求.python语言的高效编程技巧让我们这些大学曾经苦逼学了四年c或者c++的人,兴奋的不行不行的,终于解脱了.高级语言,如果做 ...
- python目前最好用的IDE——pycharm
PyCharm是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试.语法高亮.Project管理.代码跳转.智能提示.自动完成.单元测试.版本控制. ...
- minicom的安装与配置
分类: LINUX 如果项目中使用的bootloader为 u-boot,那么在用minicom向目标板传送kernel时 会发生一些错误.故若您使用的是u-boot,建议您使用kermit, ...
- Android通过HttpURLConnection链接到网络,并获取网络数据
1.判断网络是否连接 private void networkIsconnected(String str){ ConnectivityManager connMgr = (ConnectivityM ...
- 使用ViewPager实现屏幕滑动效果
oncreate中设置viewPager viewPager.setPageTransformer(true,new DepthPageTransformer());//设置页面过滤动画效果 page ...
- php常量的声明和使用
(1)声明 define("var",value) (2)先声明后使用 (3)默认区分大小写,如要不区分 define ("var",value,true); ...
- JavaScript基础--小案例:在网页指定位置弹出错误信息(十二)
案例分析:点击按钮后,在网页上指定区域,提示错误信息!5秒后,错误信息提示自动消失! <script languag="javascript" type="text ...
- 大量无线键盘存在KeySniffer漏洞-可嗅探用户输入的内容
几美元的一根天线.一个无线发射器,还有几行Python代码,有了这些,黑客就可以在几十米开外主动地记录下你的用户名.密码.信用卡.你写的稿子,总之就是你用无线键盘输入的任何东西. 黑客所利用的是一种无 ...