什么是索引以及如何使用它们来优化数据库中的查询? [复制]

Posted

技术标签:

【中文标题】什么是索引以及如何使用它们来优化数据库中的查询? [复制]【英文标题】:What are indexes and how can I use them to optimize queries in my database? [duplicate] 【发布时间】:2010-09-11 10:45:48 【问题描述】:

我正在维护一个相当大的应用程序和数据库,并注意到我们的一些存储过程中的一些数据库性能不佳。

我总是听说“添加索引”可以提高性能。我当然不是 DBA,而且我不明白什么是索引,它们为什么有用,以及如何创建它们。

我基本上需要一个索引 101。

谁能给我资源让我学习?

【问题讨论】:

@mmattax,你应该在这里接受一个答案,有几个非常好的答案 【参考方案1】:

根据经验,索引应该位于您在连接或 where 子句中使用的任何字段上(如果它们有足够的不同值以使使用索引值得,那么只有少数可能值的字段不会受益于index 这就是为什么尝试索引位字段毫无意义的原因)。

如果您的结构已经正式创建了主键(应该这样做,我从不创建没有主键的表),根据定义,这些都是索引的,因为主键需要在其上具有唯一索引。人们经常忘记他们必须索引外键,因为在设置外键关系时不会自动创建索引。由于外键的目的是为您提供一个要加入的字段,因此大多数外键可能应该被索引。

索引一旦创建就需要维护。如果您有大量数据更改活动,它们可能会变得碎片化且性能下降,并且需要刷新。阅读有关索引的在线书籍。您还可以在此处找到创建索引语句的语法。

索引是一种平衡行为,您添加的每个索引通常都会增加数据插入、更新和删除的时间,但可能会加速复杂插入、更新和删除中的选择和连接。尽管上面的经验法则是一个很好的起点,但没有一个公式可以确定什么是最佳索引。

【讨论】:

如果您要搜索的值在您的索引中是稀疏的,那么 可能 值得索引一个位列。如果您有一百万行并且只有几百行的位值为 1,而这正是您要搜索的内容,那么索引会有所帮助。与索引是否有用相关的不是可能的值,而是存储在数据库中的实际值。相反:如果您有一个 varchar(100) 列,但所有实际值都相同,则该列上的索引是无用的。【参考方案2】:

想像一个类似于图书馆卡片目录的索引。索引使您不必在每个小岛或书架上搜索一本书。相反,您可能能够从常用字段中找到您想要的项目,例如 ID、名称等。当您构建索引时,数据库基本上会创建一些单独的内容,查询可以访问而不是扫描整个表.您可以通过允许它搜索较小的数据子集或优化的数据集来加快查询速度。

【讨论】:

【参考方案3】:

索引是数据库系统用来快速查找数据的一种方法。现实世界的类比是书中的索引。如果作者/出版商在索引他们的书方面做得很好,那么读者只需查看索引就可以很容易地直接转到他们想要阅读的页面。数据库也是如此。如果在字段上创建索引,则数据库会对数据进行预排序。当对数据进行请求时,数据库使用索引来识别数据存储在硬盘上的哪个位置,并直接到那里。如果没有索引,数据库需要查看每条记录,以确定它是否符合查询条件。

查看索引的一种简单方法是考虑一副纸牌。没有索引的数据库就像一副牌,一张牌已经洗过。如果你想找到黑桃K,你需要一张一张地看每一张牌才能找到它。你可能很幸运,它可能是第一个,或者你可能很不幸,它可能是最后一个。

一个被索引的数据库,将一副牌中的所有牌按从王牌到王牌的顺序排列,每个套件都放在自己的一堆中。现在寻找黑桃王要简单得多,因为您只需要查看包含黑桃的牌堆底部即可。

我希望这会有所帮助。请注意,尽管索引在关系数据库系统中是必需的,但如果您编写太多索引,它们可能会适得其反。网络上有很多很棒的文章,您可以在索引上阅读。我建议您在深入了解它们之前先阅读一下。

【讨论】:

【参考方案4】:

索引基本上对给定列上的数据进行排序,然后存储该顺序,因此当您要查找项目时,数据库可以通过使用二分搜索(或其他一些优化的搜索方式)进行优化,而不是查看每一行。

因此,如果您要搜索的数据量很大,您绝对需要添加一些索引。

大多数数据库都有一个工具来解释您的查询将如何工作(对于 db2,它是 db2expln,可能对于 sqlserver 类似),以及一个建议索引和其他优化的工具(对于 db2,db2advis 可能与 sqlserver 类似) .

【讨论】:

大多数 SQL 数据库都实现了“EXPLAIN ”的一些变体来输出查询计划。在 PostgreSQL 中,“EXPLAIN ANALYZE ”另外运行查询并对每个部分进行计时。【参考方案5】:

如前所述,您可以拥有一个聚集索引和多个非聚集索引。在 SQL 2005 中,您还可以将其他列添加到非聚集索引中,这可以提高性能,因为索引中包含一些常用检索的​​列但不是键的一部分,从而完全消除了对表的访问。

分析器是您确定 SQL Server 数据库正在做什么的第一个工具。您可以分析整个工作负载,然后查看它推荐的索引。您还可以查看执行计划以了解索引的影响。

索引过多的问题是由于写入数据库,并且必须更新所有将具有该行记录的索引。如果您有读取性能,可能不是因为索引太多,而是因为索引太少或太不合适。

【讨论】:

【参考方案6】:

索引可以解释为寄存器中项目的排序列表。通过在索引中查找它的键,可以非常快速地在寄存器中查找项目的位置。接下来,索引中的键是指向寄存器中可以找到其余记录的位置的指针。

一个寄存器可以有很多索引,但是索引越多,插入新记录的速度就越慢(因为每个索引也需要一条新记录——按排序顺序,这也会增加时间)。

【讨论】:

【参考方案7】:

更多索引信息!

聚集索引是表中记录的实际物理布局。因此,每张桌子只能有一个。

非聚集索引就是前面提到的卡片目录。当然,这些书是按特定顺序排列的,但您可以按书本大小、页数或姓氏字母顺序排列目录中的卡片。

需要考虑的一点——创建过多的索引是一个常见的陷阱。每次更新数据时,您的数据库都必须搜索该索引并对其进行更新,将一条记录插入该表上该新行的每个索引中。在交易系统中(想想:纽约证券交易所的股票交易!),这可能是应用程序杀手。

【讨论】:

【参考方案8】:

在现有表中创建索引以更快、更有效地定位行。可以在表的一个或多个列上创建索引,并且每个索引都有一个名称。用户看不到索引,只是用来加快查询速度。

基本上,您的 DBMS 将创建某种树结构,以排序方式指向数据(来自一列)。这样可以更轻松地搜索该列上的数据。

http://en.wikipedia.org/wiki/Index_(database)

【讨论】:

正确链接:en.wikipedia.org/wiki/Index_(database) 我修复了问题中的链接【参考方案9】:

对于 mssql(可能还有其他),语法如下:

create index <indexname> on <tablename>(<column1>[,<column2>...])

【讨论】:

以上是关于什么是索引以及如何使用它们来优化数据库中的查询? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

深入MySQL索引

#yyds干货盘点# MySQL性能优化:为什么查询速度这么慢

SQL优化以及索引

MySQL 索引原理以及查询优化

MySQL索引原理以及查询优化

什么是 Solr 中良好的自动预热查询以及它们如何工作?