这一篇文章本来应该是放在 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. Oracle数据库结构

    之前写了一篇文章<Oracle-知识结构漫谈> 粗略的介绍了Oracle数据库接口,在这里再更加详细的描述一下,当做是对原有知识的巩固,温故知新. Oracle体系结构数据库的体系结构是从 ...

  2. 「SNOI2019」通信 分治建图

    根据题意 每个点可以直接与S,T相连 也可以和前面的哨站相连 暴力建边的话 有n2条边 要用分治优化建边: 类似于归并排序 先对每一层分为左半边与右半边 对每一半都拿出来先排序去重后 直接排成一条链建 ...

  3. MySQL JSON类型

    MySQL支持JSON数据类型.相比于Json格式的字符串类型,JSON数据类型的优势有: 存储在JSON列中的JSON文档的会被自动验证.无效的文档会产生错误: 最佳存储格式.存储在JSON列中的J ...

  4. ActiveMQ初步安装使用(一)

    ActiveMQ 的官网 : http://activemq.apache.org ActiveMQ 扩展出: API 接受发送 MQ 的高可用 MQ 的集群容错配置 MQ 的持久化 延时发送 签收机 ...

  5. 题解 [51nod1385] 凑数字

    题面 解析 首先设\(n\)有\(l\)位, 那么对于前\(l-1\)位,\(0\)~\(9\)都是要选上的, 而对于最高位上的数\(x\),\(1\)~\(x-1\)也是要选上的. 到这里就有了\( ...

  6. BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树

    自己独自想出来并切掉还是很开心的~ Code: #include <bits/stdc++.h> #define N 400005 #define inf 1000000000 #defi ...

  7. 收藏一个RMQ模板

    int a[1100]; int dp[maxn][20]; void rmq_init(){ for(int i=0;i<n;i++) dp[i][0]=a[i]; for(int j=1;( ...

  8. hdu 5556 Land of Farms 最大团+暴力

    Land of Farms Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

  9. POJ - 3376 Finding Palindromes manacher+字典树

    题意 给n个字符串,两两拼接,问拼接后的\(n\times n\)个字符串中有多少个回文串. 分析 将所有正串插入字典树中,马拉车跑出所有串哪些前缀和后缀为回文串,记录位置,用反串去字典树中查询,两字 ...

  10. 作为新手对于初次接触matlab的一些感受。

    使用matlab时的个人感受:1.建立一个matlab的M文件函数function xxx=aaa(b,c,d) 其中返回值为xxx,函数名为aaa,函数变量为b,c,d 要将其写在一个M文件之中,并 ...