mysql 松散索引与紧凑索引扫描(引入数据结构)
这一篇文章本来应该是放在 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 松散索引与紧凑索引扫描(引入数据结构)的更多相关文章
- MySQL优化GROUP BY-松散索引扫描与紧凑索引扫描
满足GROUP BY子句的最一般的方法是扫描整个表并创建一个新的临时表,表中每个组的所有行应为连续的,然后使用该临时表来找到组并应用累积函数(如果有).在某些情况中,MySQL能够做得更好,即通过索引 ...
- MySQL松散索引扫描与紧凑索引扫描
什么是松散索引? 答:实际上就是当MySQL 完全利用索引扫描来实现GROUP BY 的时候,并不需要扫描所有满足条件的索引键即可完成操作得出结果. 要利用到松散索引扫描实现GROUP BY,需要至少 ...
- MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析
文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...
- 高性能mysql:创建高性能的索引
本文系阅读<高性能MySQL>,Baron Schwartz等著一书中第五章 创建高性能的索引的笔记,索引是存储引擎用于快速找到记录的一种数据结构. 索引对于良好的性能非常关键,尤其是当表 ...
- MySQL 优化之 index merge(索引合并)
深入理解 index merge 是使用索引进行优化的重要基础之一.理解了 index merge 技术,我们才知道应该如何在表上建立索引. 1. 为什么会有index merge 我们的 where ...
- MySQL学习(二)索引与锁 --- 2019年1月
1.Order By 是怎么工作的 MySQL做排序是一个成本比较高的操作.MySQL会为每个线程分配一个 sort_buffer 内存用于排序,该内存大小为 sort_buffer_size. 全字 ...
- MySQL索引的原理,B+树、聚集索引和二级索引的结构分析
索引是一种用于快速查询行的数据结构,就像一本书的目录就是一个索引,如果想在一本书中找到某个主题,一般会先找到对应页码.在mysql中,存储引擎用类似的方法使用索引,先在索引中找到对应值,然后根据匹配的 ...
- mysql索引之一:索引基础(B-Tree索引、哈希索引、聚簇索引、全文(Full-text)索引区别)(唯一索引、最左前缀索引、前缀索引、多列索引)
没有索引时mysql是如何查询到数据的 索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储10 ...
- 转MySQL详解--索引
写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...
随机推荐
- Hdu 6598 Harmonious Army 最小割
N个人 每个人可以是战士/法师 M个组合 每个组合两个人 同是战士+a 同是法师+c 否则+b 对于每一个u,v,a,b,c 建(S,u,a) (u,v,a+c-2*b) (v,T,c) (S,v, ...
- springMVC的简单了解和环境搭建
一,什么mvc 模型-视图-控制器(MVC)是一个众所周知的以设计界面应用程序为基础的设计思想.它主要通过 分离模型.视图及控制器在应用程序中的角色 将业务逻辑从界面中解耦.通常, 模型负责封装应用程 ...
- linux基础_vi和vim快捷键
(1)拷贝当前行 yy,拷贝当前行向下5行 5yy,并粘贴. (2)删除当前行 dd, 删除当前行向下的5行 5dd. (3)在文件中查找某个单词.[在命令行下使用 /+关键字,回车查找,输入n就是查 ...
- shell编程expr表达式----传智播客的书linux编程基础中出现的问题
首先声明:本人是传智播客的粉丝,拥有他出的多本编程书籍,此文绝无诋毁抹黑之意. 但在linux系统编程第88页给出的while循环范例中,代码运行无法得到预期结果 原代码如下 #!/bin/sh su ...
- CCPC 2017 哈尔滨 D. X-Men && HDU 6233(思维+期望)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6233 题意:一个树上有m个人,每个人在某个节点上,每个时刻每个人可以和一个与他距离大于 1 的点进行交 ...
- BZOJ 3435 / Luogu 3920 [WC2014]紫荆花之恋 (替罪羊树 动态点分治 套 Treap)
题意 略 分析 引用PoPoQQQ的话 吾辈有生之年终于把这道题切了...QAQ (蒟蒻狂笑) Orz PoPoQQQ,我又抄PoPoQQQ的题解了 - 突然发现有旋Treap没那么难写 学习了一波C ...
- [转载]ORM-PetaPoco 小型ORM框架
轻量级ORM-PetaPoco及改进 作者:帮助您 发布:2013-04-26 06:03 分类:软件综合问题 阅读:371次 评论关闭 PetaPoco描述 PetaPoco ...
- (二)一个MFC程序,消息映射,纯代码
1.应用程序类 CWinApp https://docs.microsoft.com/zh-cn/cpp/mfc/reference/cwinapp-class?f1url=https%3A%2F%2 ...
- 【HTTP】无状态无连接的含义
无连接:服务器处理完客户的请求,并收到客户的应答后,即断开连接. 早期这么做的原因是HTTP协议产生于互联网,因此服务器需要处理同时面向全世界数十万.上百万客户端的网页访问,但每个客户端(即浏览器)与 ...
- Spring Boot中@OneToMany与@ManyToOne几个需要注意的问题
@OneToMany如果不加@JoinColumn,系统会自动在主从表中增加一个中间表. 主表: @Entity(name = "Post") public class Post ...