当前位置: 首页 > article >正文

数据库 | 索引

目录

概念

作用

适用范围

使用

1.查看索引

 2.创建索引

3.删除索引

⭐索引背后的数据结构【经典面试题】


概念

索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。

类似于目录。打个比方,数据库表就像是图书架上的书,数据就是书籍里面的内容,而索引就是书籍的目录。

作用

特点:

适用于查询频繁,增删较少的场景。

可以快速定位,检索数据;提高数据库性能。

缺点: 

引入索引,能够提高查询速度,但目录本身占据存储空间;能提高查询速度,但可能会拖慢增删改的速度(不仅要修改数据,还要调整索引)。

适用范围

对数据库表的某列或某几列创建索引,需要考虑几点:

a数据量较大,且经常对这些列进行条件查询;

b该数据库表的插入操作,及对这些列的修改操作频率较低;

c索引会占用额外的磁盘空间。

(满足以上条件时可以考虑对表中的这些字段创建索引,以提高查询效率。

使用

创建主键约束(PRIMARY KEY),唯一约束(UNIQUE),外键约束(FOREIGN KEY)时,会自动创建对应列的索引。

主要有以下三种使用方式:

1)查看索引:show index from 表名;

2)创建索引:create index 索引名 on 表名(列名);

3)删除索引:drop index 索引名 on 表名;

1.查看索引

show index from 表名;

 2.创建索引

create index 索引名 on 表名(列名);

需要注意的是:

创建索引的过程中,表数据少影响不大;但如果表很大,此时创建索引就会引起大量的cpu/硬盘IO的消耗,也是可能会把数据库搞挂了的。

创建索引会创建出一些相关的数据结构。(索引的实现通常使用B树及其变种B+树)

对于非(主键,唯一约束,外键)的字段,可以创建普通索引。

3.删除索引

drop index 索引名 on 表名;

删除索引和创建索引类似,都是比较低效的操作(对于生产环境上比较大的表,一般都是建表初始就把索引规划好的)。删除索引也是比较危险的操作,大量的IO操作也会使得数据库服务器挂掉。

⭐索引背后的数据结构【经典面试题】

索引的内部结构是怎样的?涉及到底层的数据结构(构建B+树)。

索引,引入了额外的一些数据结构(B树及其变种B+树),来增加查询的速度。默认情况下,进行条件查询操作就是在遍历表,一条一条数据都代入条件。引入索引,就是要通过其他的数据结构加快查询的速度,减少遍历表的可能性。

为什么选择B+树?

(一)首先,谈谈ArrayList和LinkedList的区别:

  • ArrayList底层是顺序表,LinkedList底层是链表;
  • ArrayList查找较快,LinkedList增删较快(这是错误的❌)

ArrayList查找并不快,只是具备随机访问能力。(随机访问 是通过下标获取元素;查找 是根据值来获取元素位置indexOf。而ArrayList查找的时候是要遍历的,时间复杂度为O(N)并没有优势)

LinkedList增删也不快,首位增删是复杂度是O(1),但是中间位置进行增删还是O(N),增加add(index,value)要遍历找index位置,所以还是O(N)。

这里的中间位置插入删除之所以是O(N),不是链表不行而是LinkedList不行。

(二)哈希表和二叉搜索树都不太适合左数据库的索引:

  • 哈希表增删查改都快,但是只能查询值相等的情况。对于“>,<,between...and..”这类比较大小的范围查询是不太适合的。
  • 二叉搜索树最坏查询速度是O(N),像AVL树/红黑树这些比较平衡的二叉搜索树是O(LogN)。如果数据库数据特别多,则二叉搜索树高度O(LogN)就会比较高,这又和查询次数相关。

如果比较实在内存中进行的,那么多比较几次少比较都影响不大;但如果是每次都要从硬盘上读取,这个就可能会产生影响:IO次数越少越好。

因此,结合上述B+树更适合用来做索引。

先认识B树:

(1)B树是一个N叉搜索树,每个节点上可能会包含N-1个值,当然也可能更少;N-1个值就把区间划分成N份;这样,在同样的数据集合下,N叉树就会比二叉树高度小很多,IO次数也降低了。

(2)B树代码的实现是非常复杂的,复杂主要是在 分裂和合并 上。

B树和B+树的区别:

  • B树每个节点N-1个值,就区分了N个区间;B+树N个值就分出N个区间。
  • B树中的值不会重复出现,B+树是可能重复出现的(况且在B+树中,父元素的值会在子元素中以最大值/最小值的姿态出现)。
  • 在叶子节点这里,B+树会把所有的叶子节点以链表的形式首位相连,此时会非常便于范围查找。(叶子节点这里已经是完整的数据集合了,前面的非叶子节点都会在这里体现出来,这也就是元素重复的意义)
  • 正因为叶子节点是全集数据,只需要把每一行(每一条记录的完整的所有列 关联到叶子节点上即可),非叶子节点只需要保存索引列(其实就是一个id)。

所以非叶子节点占用的空间相比于完整的数据集合非常小,就可以在内存中缓存;因此此时的查询又进一步减少了硬盘IO。


 


http://www.kler.cn/a/315781.html

相关文章:

  • C++中的栈(Stack)和堆(Heap)
  • ssm100医学生在线学习交流平台+vue(论文+源码)_kaic
  • 基于迭代重加权最小二乘法的算法及例程
  • 【金融风控】特征评估与筛选详解
  • C++初阶——list
  • qt QVideoWidget详解
  • 记K8s组件harbor和kuboard故障恢复
  • 桶排序和计数排序(非比较排序算法)
  • QT实现升级进度条页面
  • 计算机毕业设计之:基于深度学习的路面检测系统(源码+部署文档+讲解)
  • frpc内网穿透
  • Card View 卡片视图
  • 软媒市场新探索:软文媒体自助发布,开启自助发稿新篇章
  • 算法练习题24——leetcode3296移山所需的最小秒数(二分模拟)
  • Mysql删库跑路,如何恢复数据?
  • HDFS性能优化高频面试题及答案
  • AWS 将 OpenSearch 纳入 Linux 基金会旗下
  • 四十一、完成内容添加功能(使用go测试方法)
  • 全栈项目小组【算法赛】题目及解题
  • How do you send files to the OpenAI API?
  • 1.量化第一步,搭建属于自己的金融数据库!
  • 鸿蒙设置,修改APP图标和名称
  • Android Choreographer 监控应用 FPS
  • 如何在Chrome最新浏览器中调用ActiveX控件?
  • 什么时候用synchronized,什么时候用Reentrantlock
  • 高等数学——微分学