我可以使用Filtered Index查询“最近修改过的”行

时间:2013-09-05 23:05:44

标签: sql sql-server sql-server-2008-r2 indexing filtered-index

我正在使用SQL Server 2008-R2,但我也会对更一般的答案感兴趣...

我有一个包含数亿行的表,每行都有一个“DateModified”字段(datetime2(7))

现在我经常使用像

这样的查询来轮询该表
select * Where DateModified > @P1 from [...]

这里的参数总是最近的(就像在最后几分钟内一样)并且可能只有少数记录与该值相匹配。

我发现我在整个表上维护一个大索引,当我永远不会将索引用于其中许多值时...所以这听起来像是一个完美的使用过滤索引,我只索引我可能会查询的行...

但在这种情况下过滤器看起来像什么?我唯一的想法是过滤

where DateModified > [yesterday]

其中[yesterday]是日期文字,但是我必须定期重新定义过滤器,否则过滤器的优势会随着时间的推移而减少。

我小心翼翼地尝试ModifiedDate > DATEADD(d,-1,GETDATE()),但这给出了一个不起眼的错误......不确定这是怎么可能的。

还有其他方法可以实现这个目标吗?

最后,如果有办法做到这一点,我是否应该期望统计数据在我的情况下出现严重错误,这是否会影响我的查询性能?

我对统计数据的关注来自this article

我正在尝试将更改从一个系统传播到另一个系统并使用一些断开连接的数据...如果您想建议一种完全替代的方法来轮询“DateModified”,我很乐意考虑它。

1 个答案:

答案 0 :(得分:6)

有一段相似的要求,发现过滤器中不允许使用这些功能。

你可以做的是编写索引脚本并安排它在非高峰时段(可能是夜间)工作。这也将处理统计信息问题,因为每次创建索引时都会重新创建它们。

以下是我们最终做的事情的一个例子:

    CREATE TABLE FilteredTest (
    TestDate datetime
    );

然后按计划运行,只使用最新的行创建:

DECLARE @sql varchar(8000) = '

IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = ''IX_FilteredTest_TestDate'')
    DROP INDEX IX_FilteredTest_TestDate ON FilteredTest;

CREATE NONCLUSTERED INDEX IX_FilteredTest_TestDate ON FilteredTest (
    TestDate
)
WHERE TestDate > ''' + CONVERT(varchar(25),DATEADD(d,-1,GETDATE()) ,121) + ''';';

EXEC (@sql);