一、B-Tree索引的底层结构
  • 所有的值都是按顺序存储的,并且每一个叶子页到根的距离相同,如图所示,B-Tree索引的底层数据结构一般是B+树,反应了MyISAM索引是如何工作的。
 
 
二、B-Tree索引的使用规则
 
 
B-Tree索引适用于全键值、键值范围和键前缀查找,其中键前缀查找只适用于根据最左前缀查找。B-Tree索引支持的查询原则如下所示:
  1. 全值匹配:全值匹配指的是和索引中的所有列进行匹配。
  1. 匹配最左前缀:前边提到的索引可以用于查找所有姓Allen的人,即只使用索引中的第一列。
  1. 匹配列前缀:也可以只匹配某一列的值的开头部分。例如前面提到的索引可用于查找所有以J开头的姓的人。这里也只用到了索引的第一列。
  1. 匹配范围值:例如前边提到的索引可用于查找姓在Allen和Barrymore之间的人。这里也只使用了索引的第一列。
  1. 精确匹配某一列并范围匹配另外一列:前边提到的索引也可用于查找所有姓为Allen,并且名字是字母K开头(比如Kim,Karl等)的人。即第一列last_name全匹配,第二列first_name范围匹配。
 
因为索引树的节点是有序的,所以除了按值查找之外,索引还可以用于查询中的ORDER BY操作(按顺序查找),如果ORDER BY子句满足前面列出的几种查询类型,则这个索引也可以满足对应的排序需求。
下面是一些关于B-Tree索引的限制:
  • 如果不是按照索引的最左列开始查找,则无法使用索引。例如上面例子中的索引无法查找名字为Bill的人,也无法查找某个特定生日的日,因为这两列都不是最左数据列。
  • 如果查询中有某个列的范围查询,则其右侧所有列都无法使用索引优化查找。
三、聚簇索引
    聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。具体的细节依赖于其实现方式,但是InnoDB的聚簇索引实际上在同一个结构中保存了B-Tree索引和数据行。
    当表有聚簇索引时,它的数据行实际上存放在索引的叶子页中,这也就是说数据行和相邻的键值紧凑地存储在一起。
    下图展示了聚簇索引中的记录是如何存放的。注意到,叶子页包含了行的全部数据行,但是节点页只包含了索引列。
 
|
 
    聚簇索引可能对性能有帮助,但也可能导致严重的性能问题。
  1. 聚簇索引的优点:
    1. 数据访问更快,聚簇索引将索引和数据保存在同一个B-Tree中,因此从聚簇索引中获取数据通常比在非聚簇索引中查找要快。
    1. 使用覆盖索引扫描的查询可以直接使用页节点中的主键值。
  1. 聚簇索引的缺点:
    1. 插入顺序严重依赖插入顺序。按照主键的顺序插入是向InnoDB表中插入数据速度最快的方式,需要避免主键键值随机的(不连续且值得分布范围非常大)聚簇索引,比如使用UUID作为主键,而应该使用类似AUTO_INCREMENT的自增列。
    1. 更新聚簇索引列的代价很高,因为会强制InnoDB将每个被更新的行移动位置到新的位置。
    1. 基于聚簇索引的表在插入新行,或者主键被更新导致需要移动行时,可能面临“页分裂”的问题。当行的主键值要求必须将这行插入到某个已满的页中时,存储引擎会将该页分裂成两个页面来容纳该行,这就是一次页分裂操作。页分裂会导致表占用更多的磁盘空间。
    1. 二级索引可能比想象的更大,因为在二级索引中的叶节点包含了引用行的主键列。
    1. 二级索引访问需要两次索引查找,而不是一次。
四、InnoDB和MyISAM引擎索引的差异
    聚簇索引和非聚簇索引的数据分布有区别,以及对应的主键索引和二级索引的数据分布也有区别,通常会让人感到困惑和意外。下图展示了MyISAM和InnoDB的不同索引和数据存储方式。
    MyISAM的数据分布非常简单,按照数据插入的顺序存储在磁盘上,主键索引和二级索引的叶节点存储着指针,指向对应的数据行。
InnoDB中,聚簇索引“就是”表,所以不会像MyISAM那样需要独立的行存储。聚簇索引的每个叶节点都包含了主键值和所有的剩余列(在此例中是col2)。
    InnoDB的二级索引和聚簇索引很不同。InnoDB二级索引的叶节点中存储的不是“行指针”,而是主键值,并以此作为指向行的“指针”。
 
|
 
五、松散索引
 MySQL并不支持松散索引扫描,也就是无法按照不连续的方式扫描一个索引。通常,MySQL的索引扫描需要先定义一个起点和终点,即使需要的数据只是这段索引中很少数的几个,MySQL仍然需要扫描这段索引中的每个条目。
    下面,我们通过一个示例说明这点,假设我们有如下索引(a,b),有下面的查询:
 
|
 
 
    因为索引的前导字段是列a,但是在查询中只指定了字段b,MySQL无法使用这个索引,从而只能通过全表扫描找到匹配的行,如下图所示。
 
|
 
    了解索引的物理结构的话,不难发现还可以有一个更快的办法执行上面的查询。索引的物理结构(不是存储引擎的API)是的可以先扫描a列第一个值对应的b列的范围,然后再跳到a列第二个不同值扫描对应的b列的范围。下图展示了如果由MySQL来实现这个过程会怎样。
 
|
 
    注意到,这时就无须再使用WHERE子句过滤,因为松散索引扫描已经跳过了所有不需要的记录。
    MySQL 5.0之后的版本,在某些特殊的场景下是可以使用松散索引扫描的,例如,在一个分组查询中需要找到分组的最大值和最小值:
 
|
 
    在EXPLAIN中的Extra字段显示"Using index for group-by",表示这里将使用松散索引扫描。
六、覆盖索引
索引除了是一种查找数据的高效方式之外,也是一种列数据的直接获取方式。MySQL可以使用索引来直接获取列的数据,这样就不需要读取数据行。如果一个索引包含所有需要查询的字段的值,我们就称之为“覆盖索引”。
    覆盖索引是非常有用的工具,能够极大地提高性能。SQL查询只需要扫描索引而无需回表,会带来很多好处:
  • 索引条目数量和大小通常远小于数据行的条目和大小,所以如果只需要读取索引,那么MySQL就会极大地减少数据访问量。
  • 因为索引是按照列顺序存储的,所以对于I/O密集型的范围查找会比随机从磁盘读取每一行数据的I/O要少的多。
  • 由于InnoDB的聚簇索引,覆盖索引对InnoDB表特别有用。InnoDB的二级索引在叶子节点中保存了行的主键,索引如果二级主键能够覆盖查询,则避免对主键索引的第二次查询。
 
    当发起一个被覆盖索引的查询(也叫索引覆盖查询)时,在EXPLAIN的Extra列可以看到"Using Index"的信息。例如,表sakila.inventory有一个多列索引(store_id, film_id)。MySQL如果只需要访问这两列,就可以使用这个索引做覆盖索引,如下所示:
 
 
 
参考:
  • 《高性能MySQL》
 
 

Mysq数据库索引(B-Tree索引)的更多相关文章

  1. 论 数据库 B Tree 索引 在 固态硬盘 上 的 离散存储

    传统的做法 , 数据库 的 B Tree 索引 在 磁盘上是 顺序存储 的 , 这是考虑到 磁盘 机械读写 的 特性 . 实际上 , B Tree 是一个 树形结构 , 可以采用 链式 存储 , 就是 ...

  2. MYSQL之B+TREE索引原理

    1.什么是索引? 索引:加速查询的数据结构. 2.索引常见数据结构 顺序查找: 最基本的查询算法-复杂度O(n),大数据量此算法效率糟糕. 二叉树查找:(binary tree search): O( ...

  3. Oracle索引(B*tree和Bitmap)学习

    在Oracle中,索引基本分为以下几种:B*Tree索引,反向索引,降序索引,位图索引,函数索引,interMedia全文索引等,其中最常用的是B*Tree索引和Bitmap索引. (1).与索引相关 ...

  4. Oracle索引(B*tree与Bitmap)的学习总结

    在Oracle中,索引基本分为以下几种:B*Tree索引,反向索引,降序索引,位图索引,函数索引,interMedia全文索引等,其中最常用的是B*Tree索引和Bitmap索引.(1).与索引相关视 ...

  5. 数据库 MySQL进阶之索引

    数据库的索引非常重要,基本面试数据库的问题都在索引上,所以这里小编整理出来,一方面为了自己复习,一方面也方便大家. 一,索引前传 在了解数据库索引之前,首先有必要了解一下数据库索引的数据结构基础,那么 ...

  6. 数据库常见索引解析(B树,B-树,B+树,B*树,位图索引,Hash索引)

    B树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: B ...

  7. mysql索引 B+tree

    一.B+tree示意图 二.为什么要用索引 1.索引能极大减少存储引擎需要扫描的数据量:因为索引有序所以可以快速查找并且不用全表查找: 2.索引可以把随机IO变为顺序IO:因为B+tree在数据中保存 ...

  8. mysql B+Tree索引

    原文地址:http://blog.codinglabs.org/articles/theory-of-mysql-index.html 数据结构及算法基础 索引的本质 MySQL官方对索引的定义为:索 ...

  9. B-tree B+tree适合文件系统索引和MySQL索引

    B-树 B-树,这里的 B 表示 balance( 平衡的意思),B-树是一种多路自平衡的搜索树 它类似普通的平衡二叉树,不同的一点是B-树允许每个节点有更多的子节点.下图是 B-树的简化图. B-树 ...

随机推荐

  1. 实验四:Linux系统C语言开发环境学习

    项目 内容 这个作业属于哪个课程 班级课程主页链接 这个作业的要求在哪里 作业要求 学号-姓名 17043133-木腾飞 作业学习要求 1.学习Linux系统中如何查看帮助文档:2.在Linux系统中 ...

  2. SpringBoot入门系列(十二)统一日志收集

    前面介绍了Spring Boot 异常处理,不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/1657780.html. 今 ...

  3. hackone ssrf

    alyssa_herrera submitted a report to U.S. Dept Of Defense. Jan 29th (2 years ago) Summary:A server s ...

  4. Ratel源码-C/S事件梳理

    一.Ratel介绍 Ratel 是一个可以在命令行中玩斗地主的项目,可以使用小巧的jar包在拥有JVM环境的终端中进行游戏,同时支持人人对战和人机对战两种模式,丰富你的空闲时间! 二.玩法Demo 三 ...

  5. 管程(Monitor)概念及Java的实现原理

    互斥 互斥访问是并发编程要解决的核心问题之一. 有许多种方法可以满足临界区的互斥访问.大体上可以分为三种, 一种是软件方法,即由用户程序承担互斥访问的责任,而不需要依赖编程语言或操作系统,譬如Dekk ...

  6. Typora 使用 Markdown 嵌入 LaTeX 数学公式符号语法

    博客园不支持渲染 LaTeX 数学公式,需要用到什么公式,请复制到您所用的支持 LaTeX 的编辑器中查看实现效果.Typora 可以渲染 LaTeX 数学公式. 目录 行内与独行 行内公式 独行公式 ...

  7. 使用RTL进行硬件模型编程的局限性

    https://mp.weixin.qq.com/s/Nj_d3hwgNX4kWVtKsqMSWg   ​​   硬件模型编程,即Hardware Model Programming.在RTL抽象级别 ...

  8. Chisel3 - bind - Wire, Reg, MemPort

    https://mp.weixin.qq.com/s/AxYlRtAXjd55eoGX5l1W-A   模块(Module)从输入端口(input ports)接收输入,经过内部实现的转换逻辑,从输出 ...

  9. Chisel3 - util - Lookup

    https://mp.weixin.qq.com/s/g85Si6n37D9PYfR5hEoRQQ     实现一个查找逻辑.   参考链接: https://github.com/freechips ...

  10. 使用turtle库绘制一个红色五角星图形‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪

    import turtle n = eval(input("请输入五角星的长度")) turtle.begin_fill() #开始填充颜色 i = 0 while i < ...