数据库索引如何工作?

时间:2008-08-04 10:07:13

标签: sql database performance indexing database-indexes

鉴于索引在数据集大小增加时非常重要,有人可以解释索引在数据库无关的级别上的工作原理吗?

有关索引字段的查询的信息,请查看How do I index a database column

8 个答案:

答案 0 :(得分:3245)

答案 1 :(得分:219)

我第一次看到它对我很有帮助。谢谢。

从那时起,我对创建索引的缺点有了一些了解: 如果使用一个索引写入表(UPDATEINSERT),则实际上在文件系统中有两个写入操作。一个用于表数据,另一个用于索引数据(以及求助于它(以及 - 如果是群集的 - 求助于表数据))。如果表和索引位于同一硬盘上,则会花费更多时间。因此,没有索引(堆)的表将允许更快的写操作。 (如果你有两个索引,最终会有三个写操作,依此类推)

但是,在两个不同的硬盘上为索引数据和表数据定义两个不同的位置可以减少/消除增加时间成本的问题。这需要使用所需硬盘上的相应文件定义其他文件组,并根据需要定义表/索引位置。

索引的另一个问题是随着数据的插入,它们会随着时间的推移而碎片化。 REORGANIZE有帮助,你必须编写例程来完成它。

在某些情况下,堆比具有索引的表更有用,

例如: - 如果您有很多可以与之相对应的写入,但只能在工作时间之外每晚阅读一次,以便进行报告。

此外,群集索引和非群集索引之间的区别非常重要。

帮助我: - What do Clustered and Non clustered index actually mean?

答案 2 :(得分:191)

索引只是一种数据结构,可以更快地搜索数据库中的特定列。这个结构通常是一个b树或一个哈希表,但它可以是任何其他逻辑结构。

答案 3 :(得分:184)

经典示例"图书中的索引"

考虑一下" Book" 1000页,除以100个部分,每个部分有X页。

简单,是吗?

现在,如果没有索引页面,要查找以字母" S"开头的特定部分,除了扫描整本书之外别无选择。即:1000页

但是在开头有一个索引页面,你就在那里。而且,要阅读任何重要的特定部分,您只需要每次都一次又一次地查看索引页面。找到匹配的索引后,您可以通过跳过其他部分来有效地跳转到该部分。

但是,除了1000页之外,你还需要另外10页来显示索引页面,所以总共1010页。

因此,索引是一个单独的部分,它以排序的顺序存储索引列+指向索引行的指针的值,以便进行有效的查找。

学校里的事情很简单,不是吗? :P

答案 4 :(得分:124)

现在,假设我们要运行查询以查找名为“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”的所有行要快得多。 / p>

哈希索引的缺点

哈希表不是排序数据结构,并且有许多类型的查询,哈希索引甚至无法帮助。例如,假设您想要找出所有不到40岁的员工。你怎么能用哈希表索引做到这一点?好吧,这是不可能的,因为哈希表只适合查找键值对 - 这意味着检查相等的查询

数据库索引内部究竟是什么? 因此,现在您知道在表中的列上创建了数据库索引,并且索引将值存储在该特定列中。但是,重要的是要理解数据库索引不会将值存储在同一个表的其他列中。例如,如果我们在Employee_Name列上创建索引,这意味着Employee_Age和Employee_Address列值也不会存储在索引中。如果我们只是将所有其他列存储在索引中,那么就像创建整个表的另一个副本一样 - 这将占用太多空间并且效率非常低。

数据库如何知道何时使用索引? 当运行诸如“SELECT * FROM Employee WHERE Employee_Name ='Abc'”之类的查询时,数据库将检查查询的列上是否有索引。假设Employee_Name列确实在其上创建了索引,数据库将必须决定使用索引来查找正在搜索的值是否真的有意义 - 因为在某些情况下使用数据库索引实际上效率较低,并且更有效地扫描整个表格。

拥有数据库索引的成本是多少?

占用空间 - 表格越大,索引越大。索引的另一个性能影响是,无论何时添加,删除或更新相应表中的行,都必须对索引执行相同的操作。请记住,索引需要包含与索引所涵盖的表列中的任何内容相同的分钟数据。

作为一般规则,如果经常查询索引列中的数据,则只应在表上创建索引。

另见

  1. What columns generally make good indexes?
  2. How do database indexes work

答案 5 :(得分:67)

简单描述!!!!!!!!!!

索引只是一个数据结构,用于存储表中特定列的值。在表的列上创建索引。

示例,我们有一个名为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 :(得分:29)

只是一个快速的建议..由于索引会花费额外的写入和存储空间,因此如果您的应用程序需要更多的插入/更新操作,您可能希望使用没有索引的表,但如果它需要更多的数据检索操作,您应该去索引表。

答案 7 :(得分:21)

将数据库索引视为一本书的索引。  如果您有一本关于狗的书,并且您想要找到有关德国牧羊犬的信息,您当然可以浏览本书的所有页面并找到您要找的内容,但这当然是时间消费而不是很快。另一个选择是,您可以直接转到本书的“索引”部分,然后使用您正在查找的实体的名称(在本例中为德国牧羊犬)查找您要查找的内容,并查看页码快速找到你要找的东西。在数据库中,页码被称为指针,它将数据库定向到实体所在磁盘上的地址。使用相同的德国牧羊犬类比,我们可以有这样的东西(“德国牧羊犬”,0x77129),其中0x77129是存储德国牧羊犬的行数据的磁盘上的地址。

简而言之,索引是一种数据结构,它存储表中特定列的值,以加快查询搜索速度。