有哪些不同类型的索引,每种索引有什么好处?

时间:2020-03-06 14:44:46  来源:igfitidea点击:

有哪些不同类型的索引,每种索引有什么好处?

我听说覆盖索引和聚簇索引了,还有更多吗?我们将在哪里使用它们?

解决方案

OdeToCode有一篇很好的文章介绍了基本差异

如文章中所述:

Proper indexes are crucial for good
  performance in large databases.
  Sometimes you can make up for a poorly
  written query with a good index, but
  it can be hard to make up for poor
  indexing with even the best queries.

同样非常正确……如果我们刚开始使用它,那么我将重点介绍群集索引和组合索引,因为它们可能是我们使用最多的索引。

我将添加几个索引类型

当我们可能的值数量非常少,速度非常快且不会占用太多空间时,BITMAP

PARTITIONED允许基于某些属性对索引进行分区,这些属性通常由于存储或者性能原因而在非常大的数据库对象上具有优势。

FUNCTION / EXPRESSION索引用于根据表预先计算一些值并将其存储在索引中,一个非常简单的示例可能是基于lower()的索引或者子字符串函数。

  • 唯一-保证索引中包含的一列(或者几列)的唯一值
  • 覆盖-包括在特定查询(或者一组查询)中使用的所有列,从而允许数据库仅使用索引,而实际上不必查看表数据即可检索结果
  • 群集-通过这种方式在磁盘上对实际数据进行排序,这意味着如果查询使用群集索引来查找值,则不必采取其他步骤来查找任何数据的实际表行不包含在索引中。

对于相同类型的索引,不同的数据库系统具有不同的名称,因此请当心。例如,SQL Server和Sybase所谓的"聚集索引"在Oracle中称为"索引组织表"。

我建议我们搜索Jason Massie(http://statisticsio.com/)和Brent Ozar(http://www.brentozar.com/)的博客以获取相关信息。他们有一些有关处理索引的现实场景的文章。

PostgreSQL允许部分索引,其中仅对与谓词匹配的行进行索引。例如,我们可能只想索引那些活动的记录的客户表。这可能看起来像:

create index i on customers (id, name, whatever) where is_active is true;

如果索引中有很多列,并且有许多不活跃的客户,那么就空间(索引将存储在更少的磁盘页面中)和性能而言,这可能是一个巨大的胜利。要命中索引,我们至少需要指定谓词:

select name from customers where is_active is true;

Oracle具有b树,位图,分区和非分区,反向字节,位图联接和域索引的各种组合。

这是有关该主题的11gR1文档的链接:http://download.oracle.com/docs/cd/B28359_01/server.111/b28274/data_acc.htm#PFGRF004

SQL Server 2008具有过滤的索引,类似于PostgreSQL的部分索引。两者都允许在索引中仅包含与指定条件匹配的行。

语法与PostgreSQL相同:

create index i on Customers(name) where is_alive = cast(1 as bit);

传统观点认为,索引选择应基于基数。他们会说

For a low cardinality column like GENDER, use bitmap.  For a high cardinality like LAST_NAME, use b-tree.

对于Oracle并非如此,索引的选择应基于应用程序的类型(OLTP与OLAP)。具有位图索引的表上的DML可能导致严重的锁争用。另一方面,Oracle CBO可以轻松地将多个位图索引组合在一起,并且可以使用位图索引搜索空值。作为基本规则:

For an OLTP system with frequent DML and routine queries, use btree.  For an OLAP system with infrequent DML and adhoc queries, use bitmap.

我不确定这是否适用于其他数据库,欢迎发表评论。以下文章进一步讨论了该主题:

  • 位图索引与B树索引:何时何地?
  • 了解位图索引