数据库索引详解

索引

当我们在设计数据库的时候,对表的一些属性有时会加上索引,但索引为什么能提高检索速率呢?是不是用了索引就一定可以提高效率呢?不同索引之间有什么区别呢?搞懂这些问题是灵活运用索引的必备条件。接下来,我们将一 一进行讨论。

一.索引的本质

索引也分为不同的种类,而且也有不同的分类方法,比较常用的是普通索引和聚集索引。

1.普通索引

其实对某字段建立了索引就相当于是对该字段新建立了一个表,这个表里的元素是安照这个字段有序排列。这样有什么好处呢?好处就在于如果我们select的时候要搜索该字段,那就会在这个索引表中先查找,因为索引表是有序的,所以在检索该字段的时候就是二分搜索,速度自然会比在原表上快,然后如果我只需要这一个字段的话,查询就可以结束了,但如果还需要除索引字段的其他字段的话,那么就会根据这个索引表的字段对应到主表中,然后再获取。
看了上面讲的,是不是感觉有点迷茫?下面看一下图就会清晰很多。

(图片来源于百度)
大家可以看到这里我们以Col2建立索引之后右边有一颗二叉树,可能大家会问不是说好了是一张表吗,怎么又是二叉树了,好吧表本身就是一种树形的数据结构存储,虽然实际上很少会选取二叉树,但此处方便讲解。可以看到Col2单独的一棵树,然后每一个节点对过来是一条记录,如果我们执行 select Col2 from tablename where Col2=34;那么直接在右边的树中二叉搜索,找到了就可以返回了。如果我们执行 select * from tablename where Col2=34;那么可以看到需要的不仅仅是Col2这一个字段,那么还是先在二叉树中查找,然后找到了之后对应到主表中,然后返回整条记录。

1.索引的数据结构

通过上面的图我们可以看到,索引的本质其实就是新建了一张表,而表本质上的数据结构就是树形结构,所以索引也是树形结构。但实际运用中并没有谁用红黑树,avl树这种数据结构,一般是b+树,接下来给大家大致介绍一下b+树的构成。

(图片来源于百度)
b+树在构建时和我们之前提到的二三树很像,只是有一些改进,b+树的非叶子节点不包含value的信息,也就是说非叶子结点只起到一个导航的作用,所有的value放在了叶子结点里,这样由于B+树在内部节点上不包含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子节点上关联的数据也具有更好的缓存命中率。通常会将b+树进行优化,增加顺序访问指针。

(图片来源于百度0)
在B+Tree的每个叶子节点增加一个指向相邻叶子节点的指针,就形成了带有顺序访问指针的B+Tree。做这个优化的目的是为了提高区间访问的性能,例如图中如果要查询key为从18到49的所有数据记录,当找到18后,只需顺着节点和指针顺序遍历就可以一次性访问到所有数据节点,极大提到了区间查询效率。
可以看到b+树对于表的存储是一种很方便的数据结构。那么为什么不用红黑树呢,因为数据量大的时候,会导致这种二叉树深度太深,io次数会很多,层数很少的b+树可以有效降低io次数。

聚集索引

聚集索引和普通索引是不一样的,聚集索引是指数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同。一个表只能有一个聚集索引,因为一个表的物理顺序只有一种情况。意思就是说上面的普通索引我们可以看到是另建了一个表,然后当查询到了索引没有覆盖到的字段的时候是将这个字段映射到了主表中然后进行查询的。而聚集索引建立后主表本身就会按照这个索引的结构来存储,意思就是说主表直接就按这个来存了。这也是为什么聚集索引一定是唯一的原因,因为一张表中只能有一种存储方式。

聚集索引与普通索引

两种索引谁更快呢?这当然是没有悬念的,聚集索引更快咯,因为普通索引查到没有覆盖的字段的时候需要向主表中映射过去,然后再获取,而聚集索引因为其本身就包含了所有数据,所以一次就好~

主键与聚集索引

在我们新建一个表时,如果没有定义主键,那么表格的数据是顺序线性存储的,在定义的主键之后,因为主键默认有索引,并且在很多平台上默认是聚集索引,所以在主键定义的时候就会把整个表变为一个树形结构(如果主键是聚集索引),但要知道的是主键不一定是聚集索引,也可以是普通索引,只是很多平台默认为聚集,不要盲目划等号。

索引的利弊

那么索引既然这么快是不是越多越好呢?不存在的,因为索引本身是一个数据表,那么在插入或删除的时候就涉及到了索引表的改变,b+树的插入删除涉及到很多节点操作,或许会消耗很多时间。所以我们对于常改变的字段不宜建索引,而对于改动较少的字段就很合适,在设计表的时候我们要灵活选取,才能高效。

数据库索引与b+树的更多相关文章

  1. MySQL数据库索引之B+树

    一.B+树是什么 B+ 树是一种树型数据结构,通常用于数据库和操作系统的文件系统中.B+ 树的特点是能够保持数据稳定有序,其插入与修改操作拥有较稳定的对数时间复杂度.B+ 树元素自底向上插入,这与二叉 ...

  2. 数据库索引、B树、B+树

    数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询.更新数据库表中数据.索引的实现通常使用B树及其变种B+树. 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某 ...

  3. 数据库索引--------B/B+树、聚集、非聚集、符合索引

    摘录自博客:http://www.cnblogs.com/morvenhuang/archive/2009/03/30/1425534.html 一.引言 对数据库索引的关注从未淡出我的们的讨论,那么 ...

  4. 深入理解数据库索引采用B树和B+树的原因

    前面几篇关于数据库底层磁盘文件读取,数据库索引实现细节进行了深入的研究,但是没有串联起来的讲解为什么数据库索引会采用B树和B+树而不是其他的数据结构,例如平衡二叉树.链表等,因此,本文打算从数据库文件 ...

  5. 为什么说B+-tree比B 树更适合实际应用中操作系统的文件索引和数据库索引?

    B树: B+树 1) B+-tree的磁盘读写代价更低 B+-tree的内部结点并没有指向关键字具体信息的指针.因此其内部结点相对B 树更小.如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所 ...

  6. 为什么MySQL数据库索引选择使用B+树?

    在进一步分析为什么MySQL数据库索引选择使用B+树之前,我相信很多小伙伴对数据结构中的树还是有些许模糊的,因此我们由浅入深一步步探讨树的演进过程,在一步步引出B树以及为什么MySQL数据库索引选择使 ...

  7. B+树比B树更适合实际应用中操作系统的文件索引和数据库索引

    B+树比B树更适合实际应用中操作系统的文件索引和数据库索引 为什么选择B+树作为数据库索引结构?   背景 首先,来谈谈B树.为什么要使用B树?我们需要明白以下两个事实: [事实1]不同容量的存储器, ...

  8. 数据库索引 引用树形结构 B-数 B+数

    MySQL 为什么使用B+数 B-树和B+树最重要的一个区别就是B+树只有叶节点存放数据,其余节点用来索引,而B-树是每个索引节点都会有Data域. 这就决定了B+树更适合用来存储外部数据,也就是所谓 ...

  9. 面试经典---数据库索引B+、B-树

    大型数据库数据都是存在硬盘中的,为了操作的速度,需要设计针对外存的数据结构.而数据库索引技术就是在面试中反复被问到的一个问题:数据库索引是怎么实现的?数据库索引越大越好吗? 需要详细了解下这方面的知识 ...

随机推荐

  1. 【转载】解决SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问的方法

    1.开启Ad Hoc Distributed Queries组件,在sql查询编辑器中执行如下语句: exec sp_configure 'show advanced options',1 recon ...

  2. 航图转换相关sql

    --旧库列举所有类型航图 select distinct  c.identifier airport_icao,d.sc_code chart_type,s.namefrom special_char ...

  3. 最长公共子序列(lcs)

    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的).   比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符 ...

  4. java通过反射了解集合泛型的本质

  5. 局域网内的一些计算机可以ping通 有些ping不同

    如何查看.添加.修改.删除电脑内部路由_百度经验https://jingyan.baidu.com/article/77b8dc7fc611626174eab6cb.html

  6. Django模板语言之组合搜索

    url.py from django.conf.urls import url from django.contrib import admin from app01 import views url ...

  7. 判断手机使用网络wifi 2G 3G

    ConnectivityManager cManager = (ConnectivityManager) this .getSystemService(Context.CONNECTIVITY_SER ...

  8. c++策略模式(Strategy Method)

    别人的博客再讲策略模式时都会讲三国,策略类就是赵云的锦囊,锦囊里装着若干妙计.在打仗时想要用什么妙计,直接从锦囊里去取. 锦囊类: class context { public: context(IS ...

  9. 虚拟机ubuntu18.04设置静态IP

    说明: 网关:192.168.8.2 待设置静态IP:192.168.8.25 1.编辑:vi /etc/netplan/01-network-manager-all.yaml 打开以后内容如下: # ...

  10. lucene 第二天

    Lucene/Solr   第二天 1. 课程计划 Lucene的Field Lucene的索引库维护 lucene的查询 a) Query子对象 b) QueryParser Lucene相关度排序 ...