【问题标题】:Choosing optimal indexes for a SQL Server table为 SQL Server 表选择最佳索引
【发布时间】:2011-05-03 04:11:27
【问题描述】:

我有一个结构如下的 SQL Server 表:

CREATE TABLE [dbo].[Log](
 [LogID] [bigint] IDENTITY(1,1) NOT NULL,
 [A] [int] NOT NULL,
 [B] [int] NOT NULL,
 [C] [int] NOT NULL,
 [D] [int] NOT NULL,
 [E] [int] NOT NULL,
 [Flag1] [bit] NOT NULL,
 [Flag2] [bit] NOT NULL,
 [Flag3] [bit] NOT NULL,
 [Counter] [int] NOT NULL,
 [Start] [datetime] NOT NULL,
 [End] [datetime] NOT NULL)

该表用于记录活动。 A-E 列表示外键,Flag1-Flag3 表示某些日志状态,StartEnd 列表示活动的开始和结束。

平均而言,此表每约 30 秒更新一次,更新会进行约 50 次插入/更新。

用户可以从 UI 进行查询并过滤任何给定列以及列和列类型的所有组合的数据。

优化此表的数据检索的最佳方法是什么:

  1. 创建一个包含所有这些列的“主”索引
  2. 确定一些最常用的过滤器组合,例如[A,D,E]、[A, Start, End] 等并为它们创建索引
  3. 别的东西...

【问题讨论】:

    标签: sql sql-server indexing query-optimization


    【解决方案1】:

    我怀疑这里的任何人都只能做出猜测 - 您需要记录表的使用情况并从该使用情况中查看正在查询哪些列组合。

    1. 创建一个包含所有这些列的“主”索引

    这绝对不是一个好主意 - 如果您在 (A,B,C,D,E) 上有一个索引,并且您通过 B 和 D 的值来限制您的查询,那么该索引完全是无用。只是有用的

    • 如果您经常按全部五列查询
    • 经常通过 (A,B), (A,B,C), (A,B,C,D) 等组合

    在任何其他情况下,这是一种浪费 - 不要使用它。

    1. 确定一些最常用的过滤器组合,例如[A,D,E], [A, Start, End] 等并创建索引 为他们

    是的,这确实是保证任何成功的唯一方法。您需要查看实际发生的查询类型,然后针对这些查询进行调整。

    【讨论】:

      【解决方案2】:

      日志表很少被索引,因为索引会减慢 INSERT、UPDATE 和 DELETE 语句的速度。

      我会推荐:

      • 在过滤之前将记录加载到表中(临时或实际,索引)
      • 使用索引视图

      基本上 - 如果速度/性能是一个大问题,请在另一种形式的表中索引记录,这样日志记录就不会受到影响。

      【讨论】:

        【解决方案3】:

        一种方法是让 SQL Server 告诉您最佳用法。在表处于“典型”使用情况下运行几分钟的跟踪,然后运行 ​​Database Engine Tuning Advisor

        【讨论】:

        • ... 它返回 0 条推荐! :))))
        • 太棒了,这是要走的路:)
        • 当你做这个测试时,表中有多少条记录是问题?有时索引扫描或表扫描很糟糕,但对于小表来说,这没什么大不了的。我猜引擎调优顾问认为任何索引都不足以提高性能。
        【解决方案4】:

        在任何索引组合中,除非还引用了外键,否则不能使用内键。假设您在(A,B,C,D) 上有一个索引:

        • WHERE A=@a AND B=@b AND C=@c AND D=@d会充分利用索引
        • WHERE A=@a 可以使用索引来过滤要扫描的行范围。 WHERE A=@a AND B=@bWHERE A=@a AND C=@c 等也是如此。任何包含最左侧列 (A) 的组合都可以使用索引。
        • WHERe B=@b 不能使用索引。也不是WHERE C=@cWHERE D=@d 和任何其他错误的组合A。也就是说,如果A列不在查询限制中,则索引不可用。

        这些是非常基本的规则。除此之外,JOIN 条件可能会或可能不会被视为与 WHERE 子句相同。对于更大的结果,非覆盖索引可能会达到the tipping point。索引不仅可以满足搜索条件,还可以帮助 ORDER BY 子句。要创建的实际索引很大程度上取决于您的查询模式、I/O 功能、更新负载,尤其是数据大小管理开销(文件和备份大小的影响)。该引擎将提示您哪些索引可用于查询(Missing Indexes feature),但引擎绝不会在索引的好处与一个额外索引的成本(I/O、更新性能、数据)。有Index Design Guidelines 相当不错,但当然,您必须阅读它们。最终,选择合适的索引取决于许多因素和条件,这些因素和条件不可能给出一个千篇一律的答案。

        【讨论】:

          【解决方案5】:

          我会在开始(日期时间)上放置一个索引,仅此而已,假设很少有针对日志的查询将是从开始到最新的,而大多数查询将从起点开始。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-04-22
            • 1970-01-01
            • 2021-04-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-06-03
            相关资源
            最近更新 更多