我在哪里可以找到有关指数策略的一些指导?

Spe*_*436 22 index

我们大多数人可能会同意使用数据库索引是好的。太多的索引和性能实际上会降低。

作为一般规则,哪些字段应该被索引?
哪些字段不应该被索引?
在索引过多和不足之间取得平衡以实现性能改进而不是降级时,使用索引的规则是什么?

gbn*_*gbn 24

短的

我认为“索引过多”规则有点误导。

鉴于平均数据库大约有 98% 的读取(或更高)读取需要优化。例如,如果存在唯一索引,则 INSERT 是读取。或更新的 WHERE。我曾经读到,即使是写入密集型的数据库,仍然有 85% 的读取。

你所拥有的是低质量的索引。例子:

  • 宽聚集索引(尤其是 SQL Server)
  • 非单调聚集索引
  • 重叠索引(例如cold, colecold, cole, colf)
  • 许多对您的查询无用的单列索引(也与更有用的索引重叠)
  • 没有 INCLUDE,没有覆盖(例如所有单列索引)
  • ...

请注意,即使在 OLTP 系统中,索引也比实际数据大几倍是很常见的。

一般来说,我会从

  • 聚集索引(通常是PK)
  • 唯一索引(不是约束,这些不能覆盖)
  • 外键列

然后我会看:

  • 常见查询,看看我需要什么。每秒运行一次的查询需要调整。周日凌晨4点的报告可以等。
  • 使用 SQL Server,加权缺失索引 DMV

话虽如此,在看到事情如何发展(100 亿行之后)来调整系统后,我已经打破了某些系统的这些规则。但我永远不会考虑索引,除非我能证明我为什么这样做。

  • 你从哪里得到这些数字的?98% 似乎非常高,尤其是在“大数据”时代(即存储所有内容并希望有一天它有用) (2认同)

小智 7

很简单,关于选择哪些索引以及为什么要由 Gail Shaw 撰写的最佳系列文章之一。你可以点击这里找到文章

您提出的问题可以有 50 种不同的回答方式。这实际上归结为您拥有的数据以及如何查询这些数据。一般规则是您应该始终在每个表上都有一个聚集索引以避免堆。聚集索引通常应该尽可能小。如果该表具有聚集索引,则非聚集索引的叶页上的所有索引记录将存储相应聚集索引的记录值以用于书签查找。如果表是堆,则 SQL 将为书签查找创建唯一标识符。我不记得它的大小是 8 字节还是 16 字节。这可能最终成为一个更大的数据类型,然后说一个 INT。想象一下,在一个堆表上有 8 个非聚集索引。


小智 7

您应该分析您的数据库使用情况和负载,并确定由于缺少索引或索引过多而导致的瓶颈。然后你必须选择合适的索引——这需要对特定数据库索引技术有很好的了解。


Chr*_*ers 5

我想在这里补充一点,不同的数据库需要不同的策略。例如,让我们比较 MySQL w/InnoDB 和 PostgreSQL。

数据库

InnoDB 表基本上是主键的 b 树索引,它被扩展为包括索引条目中的行信息。不支持物理顺序扫描,所有扫描都按逻辑顺序进行。这意味着两件事:

  1. Innodb 中的顺序扫描会产生大量随机磁盘 I/O,并且

  2. 无论是否使用二级索引,都必须遍历主键索引。

  3. 在此模型中,主键查找比任何其他方法都快。

在这种情况下,在多页表中索引足够多的字段非常重要。典型的规则是索引您要过滤的所有内容。

PostgreSQL

PostgreSQL 使用堆文件,每个文件一个表(有些表可能是许多文件),其中元组从该堆的可用空间中分配。支持物理订单扫描。要使逻辑顺序扫描起作用,必须添加索引。

PostgreSQL 中的主键基本上是唯一索引的子集,其中没有值可能为 NULL。UNIQUE 约束是使用隐式索引完成的,并且支持其他几种索引类型,并在索引中进行不同的操作。

这意味着:

  1. 主键查找,假设一个相当大的表需要命中一个索引文件一个表文件。这比 MySQL 的方法要慢得多,后者只需要遍历索引并且行包含在索引中。

  2. 物理顺序扫描的性能要好得多,减少了要处理大量行的随机磁盘 I/O。

  3. 二级索引扫描的性能比 MySQL 更好,因为只需要遍历一个索引即可到达表的物理部分。

在这个模型中,索引通常是必要的,但规划者在使用索引时有更多的自由,不使用索引的影响通常不那么严重。这些表更普遍地优化(而不是专门用于 pkey 查找),因此需要的索引更少。

TL; 博士

了解您的 RDBMS。