数据库索引如何工作? [关闭]
鉴于索引在数据集大小增加时非常重要,有人可以解释索引在数据库无关的级别上的工作原理吗?
有关索引字段的查询的信息,请查看如何索引数据库列 。
#1楼
为什么需要它?
当数据存储在基于磁盘的存储设备上时,它将存储为数据块。 这些块完全被访问,使它们成为原子磁盘访问操作。 磁盘块的结构与链表大致相同; 两者都包含数据部分,指向下一个节点(或块)位置的指针,并且两者都不需要连续存储。
由于许多记录只能在一个字段上排序,我们可以声明搜索未排序的字段需要线性搜索,这需要N/2
块访问(平均),其中N
是表格跨越的块数。 如果该字段是非关键字段(即不包含唯一条目),则必须在N
块访问时搜索整个表空间。
而对于排序字段,可以使用二进制搜索,其具有log2 N
块访问。 此外,由于在给定非关键字段的情况下对数据进行了排序,因此一旦找到更高的值,则不需要搜索表的其余部分的重复值。 因此,性能提高很大。
什么是索引?
索引是一种对多个字段中的多个记录进行排序的方法。 在表中的字段上创建索引会创建另一个包含字段值的数据结构,以及指向与其相关的记录的指针。 然后对该索引结构进行排序,允许对其执行二进制搜索。
索引的缺点是这些索引需要磁盘上的额外空间,因为索引使用MyISAM引擎一起存储在表中,如果同一个表中的许多字段被索引,则此文件可以快速达到底层文件系统的大小限制。
它是如何工作的?
首先,让我们概述一个示例数据库表模式;
Field name Data type Size on disk id (Primary key) Unsigned INT 4 bytes firstName Char(50) 50 bytes lastName Char(50) 50 bytes emailAddress Char(100) 100 bytes
注意 :使用char代替varchar以允许磁盘值的准确大小。 此示例数据库包含五百万行并且未编入索引。 现在将分析几个查询的性能。 这些是使用id (已排序的键字段)的查询和使用firstName (非键未排序字段)的查询。
示例1 - 排序与未排序的字段
给定我们的r = 5,000,000
个固定大小记录的样本数据库,给出R = 204
字节的记录长度,并使用MyISAM引擎将它们存储在表中,该引擎使用默认块大小B = 1,024
字节。 该表的阻塞因子是bfr = (B/R) = 1024/204 = 5
每个磁盘块bfr = (B/R) = 1024/204 = 5
记录。 保持表所需的块总数是N = (r/bfr) = 5000000/5 = 1,000,000
个块。
鉴于id字段是关键字段,对id字段的线性搜索将需要平均N/2 = 500,000
块访问来找到值。 但由于id字段也被排序,因此可以进行二进制搜索,需要平均log2 1000000 = 19.93 = 20
块访问。 我们可以立即看到这是一个巨大的进步。
现在firstName字段既没有排序也没有键字段,因此二进制搜索是不可能的,值也不是唯一的,因此该表将需要搜索到最后的确切N = 1,000,000
块访问。 正是这种情况,索引旨在纠正。
假定索引记录仅包含索引字段和指向原始记录的指针,那么它就会小于它指向的多字段记录。 因此索引本身比原始表需要更少的磁盘块,因此需要更少的块访问来迭代。 firstName字段上的索引的模式概述如下;
Field name Data type Size on disk firstName Char(50) 50 bytes (record pointer) Special 4 bytes
注意 :MySQL中的指针长度为2,3,4或5个字节,具体取决于表的大小。
示例2 - 索引
给定我们的r = 5,000,000
条记录的样本数据库,索引记录长度为R = 54
字节,并使用默认块大小B = 1,024
字节。 索引的阻塞因子是bfr = (B/R) = 1024/54 = 18
每个磁盘块bfr = (B/R) = 1024/54 = 18
记录。 保持索引所需的块总数为N = (r/bfr) = 5000000/18 = 277,778
个块。
现在,使用firstName字段进行搜索可以利用索引来提高性能。 这允许索引的二进制搜索具有平均log2 277778 = 18.08 = 19
块访问。 要查找实际记录的地址,这需要进一步访问块读取,使总数达到19 + 1 = 20
块访问,与在非索引表中查找firstName匹配所需的1,000,000次块访问相差甚远。
什么时候应该使用?
鉴于创建索引需要额外的磁盘空间(上述示例额外增加277,778个块,增加约28%),并且太多索引可能导致文件系统大小限制引起的问题,必须仔细考虑选择正确的要索引的字段。
由于索引仅用于加速在记录中搜索匹配字段,因此,仅用于输出的索引字段仅仅是在执行插入或删除操作时浪费磁盘空间和处理时间,因此应该避免。 同样考虑到二进制搜索的性质,数据的基数或唯一性很重要。 对基数为2的字段进行索引会将数据分成两半,而基数为1,000则会返回大约1,000条记录。 如此低的基数,有效性会降低到线性排序,如果基数小于记录数的30%,查询优化器将避免使用索引,从而有效地使索引浪费空间。
#2楼
我第一次看到它对我很有帮助。 谢谢。
从那以后,我对创建索引的缺点有了一些了解:如果用一个索引写入表( UPDATE
或INSERT
),实际上在文件系统中有两个写操作。 一个用于表数据,另一个用于索引数据(以及求助于它(以及 - 如果是群集的 - 求助于表数据))。 如果表和索引位于同一硬盘上,则会花费更多时间。 因此,没有索引(堆)的表将允许更快的写操作。 (如果你有两个索引,最终会有三个写操作,依此类推)
但是,在两个不同的硬盘上为索引数据和表数据定义两个不同的位置可以减少/消除增加时间成本的问题。 这需要使用所需硬盘上的相应文件定义附加文件组,并根据需要定义表/索引位置。
索引的另一个问题是在插入数据时它们随着时间的推移而碎片化。 REORGANIZE
帮助,您必须编写例程才能完成它。
在某些情况下,堆比具有索引的表更有用,
例如: - 如果您有很多可以与之对应的写入,但只能在工作时间之外每晚阅读一次以进行报告。
此外,聚簇索引和非聚簇索引之间的区别是非常重要的。
帮助我: - 群集和非群集索引实际上意味着什么?
#3楼
索引只是一种数据结构,可以更快地搜索数据库中的特定列。 此结构通常是b树或哈希表,但它可以是任何其他逻辑结构。
#4楼
只是一个快速的建议..因为索引会花费额外的写入和存储空间,所以如果您的应用程序需要更多的插入/更新操作,您可能希望使用没有索引的表,但如果它需要更多的数据检索操作,您应该去索引表。
#5楼
简单描述!!!!!!!!!!
索引只是一个数据结构,它存储表中特定列的值。 在表的列上创建索引。
例如,我们有一个名为User的数据库表,其中有三列 - Name,Age和Address。 假设User表有数千行。
现在,假设我们要运行查询以查找名为“John”的任何用户的所有详细信息。 如果我们运行以下查询。
SELECT * FROM User
WHERE Name = 'John'
数据库软件实际上必须查看User表中的每一行,以查看该行的Name是否为'John'。 这将需要很长时间。
这就是索引帮助我们“索引用于通过基本上减少需要检查的表中的记录/行数来加速搜索查询”的地方。
如何创建索引
CREATE INDEX name_index
ON User (Name)
索引由一个表中的列值(例如:John)组成,并且这些值存储在数据结构中。
所以现在数据库将使用索引来查找名为John的员工,因为索引可能会按用户名的字母顺序排序。 并且,因为它是有序的,这意味着搜索名称要快得多,因为所有以“J”开头的名称将在索引中彼此相邻!
#6楼
现在,假设我们要运行查询以查找名为“Abc”的所有员工的所有详细信息?
SELECT * FROM Employee
WHERE Employee_Name = 'Abc'
没有索引会发生什么?
数据库软件实际上必须查看Employee表中的每一行,以查看该行的Employee_Name是否为'Abc'。 并且,因为我们希望其中的每一行都有名为“Abc”的行,所以我们不能只停止查找一行名为“Abc”的行,因为可能有其他行名为Abc 。 因此,必须搜索直到最后一行的每一行 - 这意味着数据库必须检查此方案中的数千行,以查找名为“Abc”的行。 这就是所谓的全表扫描
数据库索引如何帮助提高性能
拥有索引的重点是通过基本上减少需要检查的表中的记录/行数来加速搜索查询。 索引是一种数据结构(最常见的是B树),它存储表中特定列的值。
B树索引如何运作?
B树是最受欢迎的索引数据结构的原因是由于它们是时间有效的 - 因为查找,删除和插入都可以在对数时间内完成。 并且,B树更常用的另一个主要原因是因为可以对存储在B树内的数据进行排序。 RDBMS通常确定哪个数据结构实际用于索引。 但是,在某些具有某些RDBMS的情况下,您实际上可以指定在创建索引时希望数据库使用哪种数据结构。
哈希表索引如何工作?
使用哈希索引的原因是因为哈希表在查找值时非常有效。 因此,比较字符串相等性的查询如果使用哈希索引,则可以非常快速地检索值。
例如,我们之前讨论过的查询可以从Employee_Name列上创建的哈希索引中受益。 哈希索引的工作方式是列值将成为哈希表的键,映射到该键的实际值只是指向表中行数据的指针。 由于哈希表基本上是一个关联数组,因此典型的条目看起来像“Abc => 0x28939”,其中0x28939是对表行的引用,其中Abc存储在内存中。 在哈希表索引中查找类似“Abc”的值并返回对内存中行的引用显然比扫描表以查找Employee_Name列中值为“Abc”的所有行要快得多。
哈希索引的缺点
散列表不是排序数据结构,并且有许多类型的查询,散列索引甚至无法帮助。 例如,假设您想要找出所有不到40岁的员工。 你怎么能用哈希表索引做到这一点? 好吧,这是不可能的,因为哈希表只适用于查找键值对 - 这意味着检查相等的查询
数据库索引内部究竟是什么? 因此,现在您知道在表中的列上创建了数据库索引,并且索引将值存储在该特定列中。 但是,重要的是要理解数据库索引不会将值存储在同一个表的其他列中。 例如,如果我们在Employee_Name列上创建索引,这意味着Employee_Age和Employee_Address列值也不会存储在索引中。 如果我们只是将所有其他列存储在索引中,那么就像创建整个表的另一个副本一样 - 这将占用太多空间并且效率非常低。
数据库如何知道何时使用索引? 当运行诸如“SELECT * FROM Employee WHERE Employee_Name ='Abc'”之类的查询时,数据库将检查查询的列上是否有索引。 假设Employee_Name列确实在其上创建了索引,数据库将必须决定使用索引来查找正在搜索的值是否真的有意义 - 因为在某些情况下使用数据库索引实际上效率较低,并且更有效地扫描整个表格。
拥有数据库索引的成本是多少?
占用空间 - 表越大,索引越大。 索引的另一个性能影响是,无论何时添加,删除或更新相应表中的行,都必须对索引执行相同的操作。 请记住,索引需要包含与索引所涵盖的表列中的任何内容相同的最新数据。
作为一般规则,只有在频繁查询索引列中的数据时,才应在表上创建索引。
也可以看看
- 哪些列通常会成为好的索引?
- 数据库索引如何工作
#7楼
只需将数据库索引视为一本书的索引。
如果您有一本关于狗的书,并且您想要找到关于德国牧羊犬的信息,您当然可以翻阅书中的所有页面并找到您要找的内容 - 但这当然是耗时而不是非常快。
另一个选择是,您可以直接转到本书的“索引”部分,然后使用您正在查找的实体的名称(在本例中为德国牧羊犬)查找您要查找的内容,并查看页码快速找到你要找的东西。
在数据库中,页码被称为指针,它将数据库定向到实体所在磁盘上的地址。 使用相同的德国牧羊犬类比,我们可以有这样的东西(“德国牧羊犬”,0x77129),其中0x77129
是存储德国牧羊犬的行数据的磁盘上的地址。
简而言之,索引是一种数据结构,它存储表中特定列的值,以加快查询搜索速度。
#8楼
经典案例“书中索引”
考虑1000页的“书”,除以100个部分,每个部分有X页。
简单,对吧?
现在,如果没有索引页面,要找到以字母“S”开头的特定部分,除了扫描整本书之外别无选择。 即:1000页
但是在开头有一个索引页面,你就在那里。 而且,要阅读任何重要的特定部分,您只需要每次都一次又一次地查看索引页面。 找到匹配的索引后,您可以跳过其他部分有效地跳转到该部分。
但是,除了1000页之外,你还需要另外~10页来显示索引页面,所以总共1010页。
因此,索引是一个单独的部分,它以排序顺序存储索引列+指向索引行的指针的值,以便进行有效的查找。
学校的事情很简单,不是吗? :P
数据库索引如何工作? [关闭]相关推荐
- 数据库索引的工作原理及其种类
数据库索引的工作原理及其种类 数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询.更新数据库表中数据.索引的实现通常使用B树及其变种B+树. 在数据之外,数据库系统还维护着满足特定查找算 ...
- 数据库索引如何工作?原理
原文地址:https://blog.csdn.net/weiliangliang111/article/details/51333169 数据库索引到底是什么,是怎样工作的? 我们通过一个简单的例子来 ...
- 数据库索引优化原理,索引的工作机制
我们通过一个简单的例子来开始教程,解释为什么我们需要数据库索引.假设我们有一个数据库表 Employee, 这个表有三个字段(列)分别是 Employee_Name.Employee_Age 和Emp ...
- oracle立即关闭数据库,Oracle数据库的起步和关闭
Oracle数据库的启动和关闭 要启动和关闭数据库,必须要以具有Oracle 管理员权限的用户登陆,通常也就是以具有SYSDBA权限的用户登陆,启动一个数据库需要三个步骤: 1. 创建一个Oracle ...
- mysql 索引修复_mysql数据库索引损坏及修复经验分享
推荐:Windows Server 2003 下配置 MySQL 集群(Cluster)教程这篇文章主要介绍了Windows Server 2003 下配置 MySQL 集群(Cluster)教程,本 ...
- 数据库索引是什么?新华字典来帮你!
点击蓝色"程序猿DD"关注我哟 来源:https://zhuanlan.zhihu.com/p/57359378 学过服务器端开发的朋友一定知道,程序没有数据库索引也可以运行.但是 ...
- 大于小于优化_以MySQL为例,详解数据库索引原理及深度优化
本文内容主要来源于互联网上主流文章,只是按照个人理解稍作整合,后面附有参考链接. 一.摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引 ...
- 创建了联合索引还用在单个字段上创建索引吗_数据库 索引并不是万能的
数据库 -- 索引并不是万能的 在这里插入图片描述 索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息.如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行 ...
- 数据库索引的实现原理及查询优化
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构. 使用索引的目的在于提高查询效率,这篇文章梳理一下索引的实现原理和应用. 不同的存储引擎索引实现的数据结构不同 ...
最新文章
- Heartrate:一个牛逼的工具,Python执行实时可视化
- TopLink JPA
- osg第三方插件的编译方法(以jpeg插件来讲解)
- linux python开发环境_如何在Linux系统中搭建Python编程环境
- 通往大神之路,百度Java面试题前200页。
- 表单提交中文乱码_Java学习路线分享如何处理中文参数
- RSA加密算法【手把手解释】
- oracle vm virtualbox 虚拟光盘_虚拟机管理神器Vagrant完整操作手册来了
- linux 去掉登陆密码吗,Linux 清除 Windows用户登录密码
- JVM调优及调优参数详解
- 如何创建一个<style> tag with Javascript?
- 安卓q bubbles_Android Q Bubbles
- 小白都能理解的FTRL
- 解决办法:gtk_image_menu_item_set_image()菜单图标无法显示
- 显示器尺寸对照表_常见像素和显示屏大小对照表
- 【刘润五分钟商学院】-163生存,还是灭亡,没有中间态
- php 根据url获取域名,php 从url中获取域名的实例代码
- 深信服安服实习生面试心得
- mac上 网易mumu模拟器在打开代理后无法使用键盘 解决办法
- python制作圆形按钮_圆形按钮tkinter python