优化你的数据库索引

一、二叉查找树

众所周知,二叉查找树是每个结点最多有两个子树的树结构,通常子树被称为左子树或者右子树。二叉查找树的重要知识:对于树中的每一个节点,其左子树任意节点的值均小于该节点,其右子树的任意节点的值均大于该节点。大致结构如下图:

该图为平衡二叉树,即任意节点的左子树和右子树的高度相差不超过1。

二叉查找树的查找用的是二分查找,比如查询结点6,从根节点开始查找,因为6>5,所以从右孩子开始查找,下一步7>6 ,找到7的左孩子,因此定位到6。其时间复杂度为O(logn),查询效率高。

下面讲一下二叉查找树的缺点。当二叉树的将节点2和节点6删除时,再插入节点11、13等值,其结构变为一个线性的二叉树,如下图:

此时,查询时间复杂度变成O(n),大大降低了查询效率。

你可能会说,可以利用树的旋转的特性,来保持该树为平衡二叉树,这样其时间复杂度为维持在O(logn)。这样确实解决了查询效率的问题,但还有一个问题未解决,现在假定这些索引块都在磁盘中,以上面查找节点6为例,每次查询会进行一次IO操作,将节点读到内存中,5 -> 7 ->6的查询进行了三次IO操作,随着树的深度不断增加,大大增加了IO操作次数, 这样的检索性能比全表扫描要慢得多,无法满足优化查询的需求。

二、B-Tree

B-Tree需求遵守以下的约束:

a) 根节点至少包括两个孩子

b) 树中每个节点最多含有m 个孩子 (m>=2)

c) 除根节点和叶节点外,其他每个节点至少有ceil(m/2)个孩子

(ceil指取上限,如果m=3,则ceil(m/2)=2 )

d) 所有叶子节点都位于同一层

下图为3阶B-Tree,每个节点最多3个孩子。当然现实场景中,每个节点的孩子数n肯定远大于3,称为n阶B-Tree。每个存储块主要包含了关键字指向孩子的指针。遵守B-Tree的这些约束的目的只有一个:就是让每个索引块尽可能存储更多的信息,让树的高度尽可能减少IO次数。

假设每个非终端结点中包含有n个关键字信息,其中

a) Ki(i=1...n)为关键字,且关键字按顺序升序排序K(i-1)<Ki, 如上图的8<12

b) 关键字的个数n必须满足:[ceil(m/2)-1]<= n <= m-1,如上图关键字8和12比P1、P2、P3少一个

c) 非叶子结点的指针:P[1],P[2],....P[M] ;其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1],K[i])的子树,如上图3和5均小于8和12,而13和15均大于8和12,9和10位于8和12的区间内。

现在如果要查询15,则路径为:[17,35]:P1->[8,12]:P3->13->15,查询效率也是O(logn)。

当数据发生变动的时候,必然会存在现有结构被打乱的情况,如果是二叉查找树,可能会被打乱成线性的,则B-Tree则有相应的策略通过合并、分裂、上移、下移节点来保持其特征,不会变成线性的结构,远比二叉树矮得多。

三、B+-Tree

    B+树是B树的变体,其定义基本与B树相同,除了:

a)非叶子节点的子树指针与关键字个数相同

b)非叶子节点的子树指针P[i],指向关键字值[K[i],K[i+1])的子树,如下图 10 对应的子树中的值均小于20,同时均大于等于10。

c)非叶子节点仅用来索引,数据都保存在叶子节点中,因此B+树所有的检索都是从根部开始一直检索到叶子节点,非叶子节点仅用来存储索引,不存储数据,便可以存储更多的关键字,使得B+树相对于B树来说更矮。

d)所有叶子节点均有一个链指针指向下一个叶子节点,方便我们直接在叶子节点做范围统计。比如检索大于或等于10的数据,则在下图的第二个叶子节点直接开始从左往右检索。

结论:

B+Tree更适合用来做存储索引:

a) B+树的磁盘读写代价更低,因为B+树不存放索引的数据,只存放索引信息,因此内部节点相比B树更小 ,如果把所有同一内部节点的关键字存放在同一盘块中,这个盘块所能容纳的关键字数量也越多,一次性读入内存中的需要查找的关键字也就越多,相对来说,IO读写次数也就降低了。

b) B+树的查询效率更加稳定,由于内部节点并不是最终指向文件内容的节点,而只是叶子节点中关键字的索引,所以任何关键字的查找必须走一条从根节点到叶子节点的树,所有关键字查询的长度相同,导致每个关键字的查询效率都是相同的、稳定的O(logn)

c) B+树更有利于对数据库的扫描,因为B+树只需要遍历叶子节点便可以实现对全部关键字的扫描,比如在范围查询有更高的性能,因而B+树是现在主流的数据库索引结构。

四、Hash索引

根据哈希函数的运算,只需经过一次定位,便能找到需要查询数据所在的桶,不像B+索引需要从根节点到非叶子节点再到叶子节点才能找到数据, 这样可能会造成多次的IO访问,所以Hash索引的查询效率理论上高于B+树。

但Hash索引的缺点导致它不能做为主流索引:

a)仅仅能满足“=”,“IN”,不能使用范围查询

b)无法被用来避免数据的排序操作,因为索引的值是被Hash运算过,所以值并无规律。

c)不能利用部分索引键查询,比如组合索引会被一起被Hash运算,通过其中一个索引无法找到对应的哈希值。

d)不能避免表扫描

e)遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高

五、BitMap索引 

当表中的某个字段只有几种值的时候,比如性别字段只有男和女两种情况,如果仅仅是在这个字段实现高效的统计,此时用位图索引是一个最佳的选择,但目前很少数据库支持位图索引,比较主流的是Oracle数据库。

位图索引有一个很大的缺陷,它的锁的力度非常强大,当尝试新增或者修改某条数据的时候,通常与它在同一个位图的数据操作都会被锁住,所以它并不适合高并发系统,而适合低并发且统计需求高的系统。

更多内容请扫描二维码关注“码农TT”

原文地址:https://www.cnblogs.com/liermao12/p/10504121.html

时间: 2024-10-09 14:49:33

优化你的数据库索引的相关文章

从原理到优化,深入浅出数据库索引

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.数据库查询是数据库的最主要功能之一,我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优化,这篇文章对索引做一个系统的梳理,希望对大家有帮助. 一.MySQL有哪些索引类型 索引的分类可以从多个角度进行,下面分别从数据结构,物理存储和业务逻辑三个维度进行划分. 1.从数据结构角度 (1)B+树索引(O(log(n))) 关于B+树索引,后面会深入解析 (2)hash索引 仅仅能

数据库性能优化一:SQL索引一步到位

SQL索引在数据库优化中占有一个非常大的比例, 一个好的索引的设计,可以让你的效率提高几十甚至几百倍,在这里将带你一步步揭开他的神秘面纱. 1.1 什么是索引? SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 下面举两个简单的例子: 图书馆的例子:一个图书馆那么多书,怎么管理呢?建立一个字母开头的目录,例如:a开头的书,在第一排,b开头的在第二排,这样在找什么书就好说了,这个就是一个聚集索引,可是很多人借书找某某

【SQLSERVER】数据库索引维护/优化

好几个月没更新博客了,一方面是因为换工作和搬家的原因,比较忙:另一方面是因为觉得对数据库的理解还不够深刻,花了些时间在学习上. 最近到新公司后,做了些数据库索引优化和维护上的工作,趁着今天有空,写个博客与大家分享下,其实一些源码也是网上拷贝的,只不过是做了些改进,主要想分享的是一个优化的思路. 一.索引的利弊   优点: 1.大大加快数据的检索速度: 2.创建唯一性索引,保证数据库表中每一行数据的唯一性: 3.加速表和表之间的连接: 4.在使用分组和排序子句进行数据检索时,可以显著减少查询中分组

数据库索引以及优化

什么是索引? 索引用来快速地寻找那些具有特定值的记录. 索引是加速查询主要手段,索引是快速定位数据的技术. 索引是一种特殊的文件(innoDB(事务性数据库的首选引擎)数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针. 索引:一种特殊的目录,聚集索引和非聚集索引 聚集索引:如同字典中按照字母查询,我们把这种正文内容本身就是一种按照一定规则排列的目录称为聚集引. 非聚集索引:如同字典中按照偏旁来查询某个字,我们把这种目录纯粹是目录,正文纯粹是正文的排序. 主键就是聚集

数据库-----&gt;数据库索引-----&gt;所以原理以及如何设计并优化索引

1.数据库索引原理: 参见博客 2.如何设计数据库索引以及优化数据库索引: 参见博客

数据库索引优化。

数据库索引 大意指的是 : 查询最小结果集:更精确:搜索范围越小就越优化:减少回表数据大小: 尽可能 第一次走索引那一列的时候,取到最小的一个结果集,结果集越小,后面额回表数据就越小.系统性能就越高. 关系数据模型,二叉树

MS SqlSever一千万条以上记录分页数据库优化经验总结【索引优化 + 代码优化】[转]

对普通开发人员来说经常能接触到上千万条数据优化的机会也不是很多,这里还是要感谢公司提供了这样的一个环境,而且公司让我来做优化工作.当数据库中的记录不超过10万条时,很难分辨出开发人员的水平有多高,当数据库中的记录条数超过1000万条后,还是蛮能考验开发人员的综合技术能力. 当然不是每个公司都能请得起专业的DBA,话又说过来专业的DBA也未必能来我们公司长期工作,这就不只是薪资待遇问题了还会涉及到人家的长期发展规划了,当然我也不是专业的DBA,本着能把问题解决好就是好猫的理念. 我们先看图,数据库

数据库索引设计与优化

这篇是计算机中数据库设计类的优质预售推荐<数据库索引设计与优化>. 盖国强.姜承尧.金官丁.叶金荣.童家旺一众国内数据库界巨腕争相作序|支付宝.网易.云和恩墨联DB掌门连袂推荐的造是什么书吗? 编辑推荐 中国数据库界几大势力云集于这本旷世奇作,没读过咋好意思和DBA同行打招呼 蚂蚁(原支付宝)数据库团队资深专家携成长回忆与技术历程倾情献上最优质翻译 本书旨在--通过设计适用于现代硬件的索引,来提升关系型数据库的性能 软硬件发展让数据库性能被忽视,但数据处理量增长更快,全新索引优化设计才能根治随

[转]SqlSever2005 一千万条以上记录分页数据库优化经验总结【索引优化 + 代码优化】一周搞定

对普通开发人员来说经常能接触到上千万条数据优化的机会也不是很多,这里还是要感 谢公司提供了这样的一个环境,而且公司让我来做优化工作.当数据库中的记录不超过10万条时,很难分辨出开发人员的水平有多高,当数据库中的记录条数超过 1000万条后,还是蛮能考验开发人员的综合技术能力. 当然不是每个公司都能请得起专业的DBA,话又说过来专业的DBA也未必能来我们公司长期工作,这就不只是薪资待遇问题了还会涉及到人家的长期发展规划了,当然我也不是专业的DBA,本着能把问题解决好就是好猫的理念. 我们先看图,数