我有一个具有以下结构的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
表示某些日志状态,列Start
和End
表示开头和结尾一项活动。
平均来说,这个表每30秒更新一次,更新可以进行约50次插入/更新。
用户可以从UI进行查询,并过滤任何给定列的数据以及列和列类型的所有组合。
优化此表的数据检索的最佳方法是什么:
A,D,E
],[A, Start, End
]等,并为他们创建索引答案 0 :(得分:11)
我怀疑这里的任何人都可以做出任何猜测 - 您需要记录表格的用法,并从该用法中查看正在查询的列组合。
- 创建一个包含所有这些列的“主”索引
醇>
这绝对是不一个好主意 - 如果您有(A,B,C,D,E)索引,并且您通过B和D的值限制查询,则该索引完全是无用。它只是有用的
在任何其他情况下,这都是浪费 - 不要使用它。
- 确定一些最常用的过滤器组合,例如[A,D,E],[A, 开始,结束]等并创建索引 对他们来说
醇>
是的,这是承诺任何成功的唯一方式。您需要查看实际发生的查询类型,然后对其进行调整。
答案 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=@b
,WHERE A=@a AND C=@c
等也是如此。中最左边的列(A
)的任何组合都可以使用索引。WHERe B=@b
无法使用索引。也不是WHERE C=@c
,WHERE 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)上放置一个索引,这就是全部,假设对日志的查询很少是从最初开始的,而且大多数将从起点开始。