【问题标题】:Indexes on a Read Only Database只读数据库上的索引
【发布时间】:2014-11-15 17:27:13
【问题描述】:

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

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

我正在查看索引,大多数关于索引的教程和信息都关注 SELECT 性能和 INSERT / UPDATE 性能与引入索引之间的权衡。

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

或者换一种说法,你能“过度索引”一个只读数据库吗?

【问题讨论】:

  • 如果您无法控制最终用户将执行哪些搜索,那么您将遇到性能问题;所以你应该分析你的系统将要发出的查询,并为这些查询适当地索引。过多的索引维护会降低插入/更新性能,但也会需要更多内存来缓存索引(假设它们都在使用,这就是你创建它们的原因,它们都会消耗 RAM)。

标签: c# sql sql-server-ce-4


【解决方案1】:

实际上,iirc 是一个特定于仓库的系统,SybaseIQ 正是这样做的——将每个字段放在自己的索引中。但我不喜欢这个主意。我非常怀疑如果某件事在那边是个好主意,那么它在任何地方都是一个好主意。我将其称为 Tomm Carr 通用规则,适用于所有情况下所有情况下的所有情况,或简称为 TCUR。

这是:

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

这仅仅意味着我们可以开发的最好的规则、标准或默认值永远只是一个好的开始。

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

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

针对最常执行的查询调整系统。然后在不影响第一组的情况下,尽可能少地进行调整。

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

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。称它们为 results 索引和 filtering 索引。所以过滤是使用更小的行(每个 I/O 更多的行)执行的,当所有工作完成后,然后转到结果索引以获得更少的答案。

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 请检查您的“否”:有很多选项会减慢查询计划,可能难以缓存数据(因为有很多选项很可能不会重复使用相同的索引),可以假设从磁盘读取更多...所以这不能是绝对的“否”。它可以减慢速度,而不是提高性能。
    猜你喜欢
    • 2011-04-09
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-17
    相关资源
    最近更新 更多