一、摘要
本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题 。特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等 。为了避免混乱,本文将只关注于BTree索引,因为这是平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论 。
二、常见的查询算法及数据结构
为什么这里要讲查询算法和数据结构呢?因为之所以要建立索引,其实就是为了构建一种数据结构,可以在上面应用一种高效的查询算法,最终提高数据的查询速度 。
2.1 索引的本质
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构 。提取句子主干,就可以得到索引的本质:索引是数据结构 。
2.2 常见的查询算法
我们知道,数据库查询是数据库的最主要功能之一 。我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优化 。那么有哪些查询算法可以使查询速度变得更快呢?
2.2.1 顺序查找(linear search )
最基本的查询算法当然是顺序查找(linear search),也就是对比每个元素的方法,不过这种算法在数据量很大时效率是极低的 。
- 数据结构:有序或无序队列
- 复杂度:O(n)
int SequenceSearch(int a[], int value, int n)
{
int i;
for(i=0; i<n; i++)
if(a[i]==value)
return i;
return -1;
}
2.2.2 二分查找(binary search)
比顺序查找更快的查询方法应该就是二分查找了,二分查找的原理是查找过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较 。如果在某一步骤数组为空,则代表找不到 。
- 数据结构:有序数组
- 复杂度:O(logn)
int BinarySearch2(int a[], int value, int low, int high)
{
int mid = low+(high-low)/2;
if(a[mid]==value)
return mid;
if(a[mid]>value)
return BinarySearch2(a, value, low, mid-1);
if(a[mid]<value)
return BinarySearch2(a, value, mid+1, high);
}
2.2.3 二叉排序树查找
二叉排序树的特点是:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉排序树 。
- 若b是空树,则搜索失败,否则:
- 若x等于b的根节点的数据域之值,则查找成功;否则:
- 若x小于b的根节点的数据域之值,则搜索左子树;否则:
- 查找右子树 。
- 数据结构:二叉排序树
- 时间复杂度:O(log2N)
其原理是首先根据key值和哈希函数创建一个哈希表(散列表),燃耗根据键值,通过散列函数,定位数据元素位置 。
- 数据结构:哈希表
- 时间复杂度:几乎是O(1),取决于产生冲突的多少 。
分块查找又称索引顺序查找,它是顺序查找的一种改进方法 。其算法思想是将n个数据元素”按块有序”划分为m块(m ≤ n) 。每一块中的结点不必有序,但块与块之间必须”按块有序”;即第1块中任一元素的关键字都必须小于第2块中任一元素的关键字;而第2块中任一元素又都必须小于第3块中的任一元素,依次类推 。
算法流程:
- 先选取各块中的最大关键字构成一个索引表;
- 查找分两个部分:先对索引表进行二分查找或顺序查找,以确定待查记录在哪一块中;然后,在已确定的块中用顺序法进行查找 。
推荐阅读
- Linux最常用命令!简单易学,能解决95%以上的问题
- 老婆瘫痪了可以离婚吗 丈夫瘫痪我能离婚吗
- 在床上可以做的减肥运动有什么?
- 请问黄芪泡水喝可以减肥吗
- 茶叶美容7个秘方
- 一个新的快手号怎么才可以养好 快手老号怎么养号
- 作文500字,珍惜的作文 以珍惜为话题的作文
- 淡奶可以做什么美食
- 车辆应该什么时候年审?最晚可以超几天?逾期上路会有什么处罚?
- 眼镜店可以修复镜框吗