只读数据库上的索引

本文关键字:索引 数据库 只读 | 更新日期: 2023-09-27 18:30:38

我不确定这是否是这个问题的地方,但这里是:

我有一个只读数据库,它包含许多使用 c# 桌面应用程序访问和搜索的表。

我正在查看索引,大多数有关索引的教程和信息都集中在引入索引的 SELECT 性能和插入/更新性能之间的权衡上。

我的问题是,对于只读数据库,在每一列和每列组合上放置索引有什么缺点?(假设我也不太关心数据库的大小?

或者换句话说,您可以"过度索引"只读数据库吗?

只读数据库上的索引

实际上,iirc,一个特定于仓库的系统,SybaseIQ就是这样做的 - 将每个字段放在自己的索引中。但我不喜欢这个想法。我非常怀疑这样的想法,即如果某件事在那里是一个好主意,那么它在任何地方也是一个好主意。我称之为汤姆卡尔通用规则,适用于所有情况、所有条件、所有情况,简称TCUR。

这是:

除了汤姆卡尔 适用于所有情况和所有情况的普遍规则 在所有情况下的条件,没有一条规则适用于 所有情况下的所有情况,所有情况。

这仅仅意味着,我们可能制定的最佳规则,标准或默认值永远只能是一个良好的开端。

因此,如果你想设计最好的仓库,你将不得不投入工作。现在,这是一个仓库这一事实意味着您可以比在 OLTP 系统中更轻松地使用索引。但更多并不能转化为"随意扔掉它们"。

分析查询。将它们从最常使用到最不常用进行排序。有些仅用于每月、每季度或每年生成的报告。你几乎可以忘记这些 - 即使你可以将执行时间从十分钟减少到十秒......这可能不值得付出努力。

针对最常执行的查询调整系统。然后使用频率较低的,如果可以的话,在不影响第一组的情况下进行调整。

哦,如果可以的话,还有一句话,关于覆盖索引。通常,我们被告知要查看查询提到的每个字段:

select  a, b, c
from    table
where   e = f
    and g > something;

然后,覆盖索引将包含字段 a、b、c、e、f 和 g。

不一定

是一个好主意,或者至少不一定是最好的主意。考虑到过滤可能涉及数百、数千或数百万条记录,然后才能得出非常小甚至只有一个结果。没有理由在仅使用 e、f 和 g 进行所有过滤时围绕包含字段 a、b 和 c 的索引进行洗牌。这里最好的设计是两个覆盖索引:一个带有a,b,c,另一个带有e,f,g。将它们称为结果索引和过滤索引。因此,过滤是使用较小的行(每个I/O更多的行)执行的,当所有工作完成后,然后转到结果索引以获得更少的答案。

但不要忘记 TCUR 也适用于这里。只有好的、彻底的分析才能告诉你该走哪条路。

让我们考虑一下在索引表中插入/更新行时会发生什么(假设我们使用的是标准的 B 树索引)。该条目将被添加到表本身中,以及在表上的每个索引中创建一个条目。这就是产生时间/空间开销的原因。

直接回答您的问题是否定的,除了生成索引的初始时间/空间开销之外,在每个表的每一列上放置索引都没有重大缺点。请记住,执行查询时,每个表最多只能使用一个索引。通过拥有大量索引/复合索引,您可以在决定使用哪些索引时为优化器提供最佳选择。

话虽如此,开始生成任意索引很少考虑是很混乱的。如果我是你,我会看看你需要哪些查询来更快地运行并开始相应地生成索引。