年前项目组接微信公众号。

上线之后,跟微信相关的用cid列的查询会话的SQL变慢了几十倍!思考这个问题思考了非常久。从出现以来一直是我心头的一个结。cid这一列是建了索引的,普通的cid列更新都没问题,为何仅仅有微信的有问题?同样的前缀又是怎样影响索引的?

   分析过程
    1.explain下微信cid的查询。微信的cid会以mid-qqwanggou001为前缀插入数据
explain
select *
from analysis_sessions
where cid = "mid-qqwanggou001-b99359d9054171901c0"

分析结果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" width="867" height="100" />

从explain分析能够看出。这个查询使用了索引,可是innodb觉得有165万行数据须要给mysqlserver筛选(也就是用where条件过滤)。

假设这些庞大的数据在内存,遍历一遍花不了多少时间。可是极有可能,这些数据是在磁盘上的。这么多的数据从磁盘读取然后加载内存。大量磁盘IO必定是十分的耗时的。

相比内存的电子运动。磁盘机械臂的物理运动要慢好几个数量级。

2.分析普通cid的查询

取数据进行explain。cid = "sid-a2f9047ddf528d837e5f60843c83aae9"。这个数据是不带公共前缀的。

   
explain
select *
from analysis_sessions
where cid = "sid-a2f9047ddf528d837e5f60843c83aae9"

分析结果例如以下:

同样的列,同样的索引。这次存储引擎向mysqlserver仅仅返回了一行数据。也就是说innodb仅仅须要读取一个二级索引的叶子节点。

相对于上面那个sql的IO,压力显然小非常多。

初步分析结论:带有长前缀的cid查询。innodb存储引擎会向mysql上端server返回百万级别的数据。

这仅仅是现象,我还是想问,同样的表,同样的列,同样的索引结构(B+树索引)。同样的查询,仅仅不同的数据。结果为何有差么大的区别?

近一步分析

纠结这个问题非常久了,直到前天晚上散步时候。无意的会想到了 explain结果的key_len这一列。这一列我从来不看,觉得没用。可是27与cid这一列50个varchar的定义格格不入。27明显小于50,首先能够肯定,这个索引用的是前缀索引,说白了,截取了字符串的前面一部分作为索引数据。analysis_session表用的gbk编码。也就是说,索引须要2个字节表示一个varchar。解释一下key_len

27 = 2 * 12 + 2 + 1

27位的索引,仅仅索引了前面12个字符。中间的2存储长度。后面的一个字节存储Null信息,由于这一列是同意Null的。

终于结论:问题到这已经非常明了了,微信cid的前缀是17个字符的,大于前缀索引的12个字符,也就是说。全部存储微信cid数据(百万级别)B+树叶子节点将仅仅有一个B+树非叶节点的指针指向这里。于是。当你查微信cid相关的数据时,全部微信cid将被返回给mysqlserver进行where过滤了,效率上讲,这是非常恐怖的。

索引确实还是被用上了。不然会造成全表扫描。可是这个数据设计的有问题。B+树的查找效率是O(LogN)的,可是遇上这个数据,立马变成O(N),相当于一个局部全表扫描。

那么合理的猜測。仅仅要有新增的微信cid,微信cid的查询仅仅会变的更慢。

引申,更佳的代码 practice:

varchar,blob, text等边长数据建索引的时候。数据库会自己主动建前缀索引,于是B+树不会索引整个字段的部分。非常多同学喜欢用前缀作为字符串的标志,这次要注意了,有前车之鉴了。前缀存入mysql之后会减少检索效率,前缀越长。B+树查询的效率越低。

这里给出代码的建议:

1.将前缀作为后缀,startWith改为endWith

2.不要尝试后缀模糊搜索,like "%.com",这样的做法更糟糕,全然用不了索引,于是全表扫描。

字符串的公共前缀对Mysql B+树查询影响回溯分析的更多相关文章

  1. MySQL知识树-查询语句

    在日常的web应用开发过程中,一般会涉及到数据库方面的操作,其中查询又是占绝大部分的.我们不仅要会写查询,最好能系统的学习下与查询相关的知识点,这篇随笔我们就来一起看看MySQL查询知识相关的树是什么 ...

  2. LeetCode 14. Longest Common Prefix字典树 trie树 学习之 公共前缀字符串

    所有字符串的公共前缀最长字符串 特点:(1)公共所有字符串前缀 (好像跟没说一样...) (2)在字典树中特点:任意从根节点触发遇见第一个分支为止的字符集合即为目标串 参考问题:https://lee ...

  3. leetcode_最长公共前缀

    题目:Write a function to find the longest common prefix string amongst an array of strings. 题解:给出的函数为: ...

  4. LeetCode 7最长公共前缀

    编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...

  5. [LeetCode]14. Longest Common Prefix最长公共前缀

    Write a function to find the longest common prefix string amongst an array of strings. If there is n ...

  6. LeetCode刷题-最长公共前缀(简单)

    题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow ...

  7. 最长公共前缀 leetcode 14

    方法一(纵向扫描) 解题思路 先计算出数组中最小的字符串长度,这样就避免了越界的情况,思路更加明确,但同时时间复杂度就相应的上升了. 先计算所有字符串在同一列上的字符是否相同,然后依次向后延伸. 代码 ...

  8. 每日一道 LeetCode (5):最长公共前缀

    前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee: https://gitee.com ...

  9. Leetcode13. 罗马数字转整数Leetcode14. 最长公共前缀Leetcode15. 三数之和Leetcode16. 最接近的三数之和Leetcode17. 电话号码的字母组合

    > 简洁易懂讲清原理,讲不清你来打我~ 输入字符串,输出对应整数 ![在这里插入图片描述](https://img-blog.csdnimg.cn/63802fda72be45eba98d9e4 ...

随机推荐

  1. 一个java高级工程师的进阶之路【转】

    宏观方面 一. JAVA.要想成为JAVA(高级)工程师肯定要学习JAVA.一般的程序员或许只需知道一些JAVA的语法结构就可以应付了.但要成为JAVA(高级) 工程师,您要对JAVA做比较深入的研究 ...

  2. .Net中的插件框架Managed Extensibility Framework

    Managed Extensibility Framework(MEF)是微软的一个用来扩展.NET应用程序的框架,它最初为了满足Visual Studio里的编辑器的需求,比如说,延迟加载所有东西和 ...

  3. 给Android组件添加事件一个很好用的方法

    在这里想和大家分享一下很好用的添加事件方法,特别是在处理ListView里的Item事件的时候,很方便. 首先,在XML里布局的时候,添加这样一个属性: android:onClick="C ...

  4. C# iTextSharp 生成 PDF

    使用iTextSharp在Asp.Net中操作PDF系列文章 目录 http://www.cnblogs.com/CareySon/category/332146.html 实战 iTextSharp ...

  5. C#程序集系列07,篡改程序集

    以下几个方面用来区分不同的程序集:○ 程序集名称:Name○ 程序集版本:Version○ 程序集公匙: Public Token○ 程序集文化:Culture 如果没有很严格地按照上面的几个方面来创 ...

  6. 【mysql】在mysql中更新字段的部分值,更新某个字符串字段的部分内容

    在mysql中更新字段的部分值,更新某个字符串字段的部分内容 sql语句如下: update goods set img = REPLACE(img,'http://ozwm3lwui.bkt.clo ...

  7. mr

    大数据技术 —— MapReduce 简介 本文为senlie原创,转载请保留此地址:http://www.cnblogs.com/senlie/ 1.概要很多计算在概念上很直观,但由于输入数据很大, ...

  8. 音频视频解决方案:GStreamer/ffmpeg/ffdshow/directshow/vfw

    音频视频编程相关:GStreamer/ffmpeg/directshow/vfw linux和window下几种流行的音频视频编程框架作一个总结,防止自己迷惘,免于晕头转向. 一.GStreamer ...

  9. 《JavaScript网页特效经典300例》

    <JavaScript网页特效经典300例> 基本信息 作者: 杨磊    张志美 丛书名: 百炼成钢系列丛书 出版社:电子工业出版社 ISBN:9787121220524 上架时间:20 ...

  10. APP的上线和推广——线上推广渠道

    本文版权归个人所有,如需转载请注明出处http://www.cnblogs.com/PengLee/p/4637080.html 目录 应用商店 互联网开放平台 软件下载中心 媒体社交平台 刷榜推广 ...