这一篇文章本来应该是放在 mysql 高性能日记中的,并且其优化程度并不高,但考虑到其特殊性和原理(索引结构也在这里稍微讲一下)

一,mysql 索引结构 (B、B+树)

要问到 mysql 的索引用到什么数据结构,我相信大部分都能回答出来,没错,就是 B+ 树。那再问为什么要用 B+ 树呢,与红黑树,hash 表又分别有什么区别呢,问到这里可能就难住了一些没思考过的轻度玩家了。这里简单描述一下

B 树与红黑树的区别,有数据结构基础的同学应该可以讲出来,红黑树是平衡二叉树的一个变种,利用红黑树的 5 个特征保证其近乎平衡,记住,红黑树降低的左转右转的递归向上,但其并不是绝对平衡,但非极端情况下,我们也可以说红黑树的查询和插入都是 log2n 的时间复杂度;而 B 树可以理解为平衡 n 插树,每个数的节点并不是一个值,而是一个数组,每两个数值之间指向一个在两者之间范围的新节点,这里可以看到对于相同的数据量,B 树的高度远远小于,根据官方给出一般索引的高度不会超过 5 的高度计算,3亿的数据量仅需要每个节点 50 个数据,mysql 在每个节点的遍历也是用最快的二分查找,所以查询一个 3亿 数据量的时间复杂度仅为 5log250,算下来几乎为常数级

B 树与 hash 表的区别,hash 的查询会比 B 树更快一些,好的 hash 表甚至可以达到 1-5 次查询得到结果,但与已经是常数级的 B 树相比,并没有太大的一个优化,但 hash 的插入却很容易产生 hash 冲突,现有解决 hash 冲突的方法无不是需要耗费大量时间进行重新 hash,相较微量的查询优化,写的效率过低导致 mysql 不可能使用 hash 表作为索引结构。

mysql 的索引结构其实本质是 B 树的一个变种结构 -- B+ 树,相较 B 树,B+ 树更适用于文件型索引,其每个非叶子节点存储的只是用于索引排序的辅助数值,而真正的数据都放在叶子节点,对于 mysql 这种不仅仅存单纯的排序值,而是关系型数据的 db,当然是 B+ 树更适合作为索引结构,当然还有一个小的优化点是子节点之间是有指针连接的,加快了范围查找的速度。

,复合索引结构

对于主键索引,肯定索引结构是按一个主键的顺序组合的 B 树,但对于一个含有两个列的复合索引,它的树状结构是什么样呢?

对于复合索引 Index(A,B),B 树的排序是按 A 列的数值为第一要素,B 列的数值为第二要素进行排序,这也就是为什么我们查询语句时,条件语句必须保证最左原则才可以利用到索引

这里引入一些题外话,聚簇索引(Innodb)和非聚簇索引(myisam),因为讲到索引结构,这里引入这个话题,也是 mysql 中比较常用的两大引擎的一个区别,聚簇索引的索引的叶节点存放的直接是数据的叶节点,当使用辅助(符合)索引查询时,其叶子节点存放的是主键的值,所以通过符合索引查找非覆盖索引数据时,都会进行两次查询,并且查询主键的速度没有 myisam 的速度快;非聚簇索引指索引的叶节点存放的是数据的页数据指针,辅助索引存的同样是指针。两者各有千秋,不能说哪个好哪个坏,按业务自身选择即可

回到正题,那对于复合索引的查询是如何的过程,那如果真的想要只查 B 又想用到索引,该如何使用呢?引入我们的第三个话题

,紧凑索引与松散索引

如果不遵守最左原则,where b = xxx,就会使用紧凑索引遍历的方式,进行全表扫表。而我们如果真的有些情况,需要查出符合 B 条件但对 A 不进行限制的情况,应该如何处理,可能有些同学会新开一个独立索引仅包含 B 列,这样虽然能达到我们的目的,但难免有些多余。mysql 也是也能很好的进行跳跃松散索引扫描,只是 mysql 优化器无法自动进行,必须在查询语句中进行必要的声明。 select * from xxx where B = xxx group by A; 添加 group by 字段后,会先根据 A 索引分组后,会在每个 A 的范围内使用索引进行快速查询定位所需要的 B 列,这就叫做松散索引扫描,比新建一个索引的效率会慢 A 的 distinct 倍,但省去了新索引的消耗。

--业务程序员

mysql 松散索引与紧凑索引扫描(引入数据结构)的更多相关文章

  1. MySQL优化GROUP BY-松散索引扫描与紧凑索引扫描

    满足GROUP BY子句的最一般的方法是扫描整个表并创建一个新的临时表,表中每个组的所有行应为连续的,然后使用该临时表来找到组并应用累积函数(如果有).在某些情况中,MySQL能够做得更好,即通过索引 ...

  2. MySQL松散索引扫描与紧凑索引扫描

    什么是松散索引? 答:实际上就是当MySQL 完全利用索引扫描来实现GROUP BY 的时候,并不需要扫描所有满足条件的索引键即可完成操作得出结果. 要利用到松散索引扫描实现GROUP BY,需要至少 ...

  3. MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析

    文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...

  4. 高性能mysql:创建高性能的索引

    本文系阅读<高性能MySQL>,Baron Schwartz等著一书中第五章 创建高性能的索引的笔记,索引是存储引擎用于快速找到记录的一种数据结构. 索引对于良好的性能非常关键,尤其是当表 ...

  5. MySQL 优化之 index merge(索引合并)

    深入理解 index merge 是使用索引进行优化的重要基础之一.理解了 index merge 技术,我们才知道应该如何在表上建立索引. 1. 为什么会有index merge 我们的 where ...

  6. MySQL学习(二)索引与锁 --- 2019年1月

    1.Order By 是怎么工作的 MySQL做排序是一个成本比较高的操作.MySQL会为每个线程分配一个 sort_buffer 内存用于排序,该内存大小为 sort_buffer_size. 全字 ...

  7. MySQL索引的原理,B+树、聚集索引和二级索引的结构分析

    索引是一种用于快速查询行的数据结构,就像一本书的目录就是一个索引,如果想在一本书中找到某个主题,一般会先找到对应页码.在mysql中,存储引擎用类似的方法使用索引,先在索引中找到对应值,然后根据匹配的 ...

  8. mysql索引之一:索引基础(B-Tree索引、哈希索引、聚簇索引、全文(Full-text)索引区别)(唯一索引、最左前缀索引、前缀索引、多列索引)

    没有索引时mysql是如何查询到数据的 索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储10 ...

  9. 转MySQL详解--索引

    写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...

随机推荐

  1. shell脚本基础编写

    shell脚本的格式 名称:Shell 脚本文件的名称可以任意,但为了避免被误以为是普通文件,建议将 .sh 后缀加上,以表示是一个脚本文件. shell 脚本中一般会出现三种不同的元素: 第一行的脚 ...

  2. github仓库管理项目

    一,建立本地git仓库 首先,git要求使用者必须提供自己的身份标识,为此我们需要在git bash中执行以下命令: git config --global user.name  'aa.Tessst ...

  3. [唐胡璐]Selenium技巧- ReportNG替换TestNG默认结果报告

    TestNG默认的报告虽然内容挺全,但是展现效果却不太理想,不易阅读。因此我们想利用ReportNG来替代TestNG默认的report。 什么是ReportNG呢?这里不多说,请直接参见:http: ...

  4. 关于github报错 ssh: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository.

    今天上午写demo的时候,突然pull不下代码了,报了一下这样情况的错误: 看了一下代码,怀疑是网路错误,因为在这以前一切都正常的,然后将代码复制搜索了一番,解决办法有很多什么配置config啦,gi ...

  5. struts2之多文件上传与拦截器(8)

    前台jsp <s:form action="uploadAction" enctype="multipart/form-data" method=&quo ...

  6. bzoj4009: [HNOI2015]接水果(整体二分)

    题目描述 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, 她觉得这个游戏太简单了,于是发明了一个更加难的版本. 首先有 ...

  7. 有关 C# WebAPI知识

    1.[懒得安分博客总结的很全面] 2.关于基础类型作入参数的问题      参照此博客[ASP.NET WebAPI String 传值问题] 3.代码说明     using System; usi ...

  8. [Luogu] 国王游戏

    https://www.luogu.org/problemnew/show/P1080 按照 a * b 排序 高精度 #include <bits/stdc++.h> using nam ...

  9. 【线性代数】2-7:转置与变换(Transposes and Permutation)

    title: [线性代数]2-7:转置与变换(Transposes and Permutation) toc: true categories: Mathematic Linear Algebra d ...

  10. JS如何实现在微信中调用外部浏览器打开指定链接

    使用方法,复制以下贴到index.php 顶部就可以了.场景 比如网页包含视频播放  在QQ\WX打开QQ\WX直接调用自己的播放器播放,而且播放完成还有AD推送,非常恶心,所以有了以下代码有乱码的话 ...