为SQL Server表选择最佳索引

时间:2010-10-31 20:39:45

标签: sql sql-server indexing query-optimization

我有一个具有以下结构的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. 别的......

5 个答案:

答案 0 :(得分:11)

我怀疑这里的任何人都可以做出任何猜测 - 您需要记录表格的用法,并从该用法中查看正在查询的列组合。

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

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

  • 如果您经常通过所有五列查询
  • 通过像(A,B),(A,B,C),(A,B,C,D)这样的组合经常

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

  
      
  1. 确定一些最常用的过滤器组合,例如[A,D,E],[A,   开始,结束]等并创建索引   对他们来说
  2.   

是的,这是承诺任何成功的唯一方式。您需要查看实际发生的查询类型,然后对其进行调整。

答案 1 :(得分:2)

日志表很少被编入索引,因为索引会降低INSERT,UPDATE和DELETE语句的速度。

我会建议:

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

基本上 - 如果速度/性能是一个大问题,请使用另一种形式的表索引记录,以便不会影响日志记录。

答案 2 :(得分:2)

在任何索引组合中,除非也引用外键,否则不能使用内部键。假设您有(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非常好,但当然,你必须阅读它们。最终,选择合适的指标取决于许多因素和考虑因素,这些因素和考虑因素不足以给出切割答案。

答案 3 :(得分:1)

一种方法是让SQL Server告诉您最佳用法。当表处于“典型”使用状态时运行跟踪几分钟,然后运行数据库引擎优化顾问

答案 4 :(得分:0)

我会在start(datetime)上放置一个索引,这就是全部,假设对日志的查询很少是从最初开始的,而且大多数将从起点开始。