4

I am using SQL Server 2008-R2, but I'd be interested in a more general answer too ...

I have a table with hundreds of millions of rows, each with a "DateModified" field (datetime2(7))

Now I very frequently poll that table with a query like

select * from table where DateModified > @P1 

Here the parameter is always recent (like within the last few minutes) and there are probably only a few records matching that value.

It occurs to me that I am maintaining a big index on the whole table, when I will never use the index for many of those values ... so this sounds like a perfect use of a Filtered Index where I only index the rows that I would possible be querying against...

But in this case what could the filter look like? My only idea was to Filter on

where DateModified > [yesterday]

where [yesterday] is a date literal, but then I'd have to re-define the filter periodically or the advantage of the filter would diminish over time.

On a whim I tried ModifiedDate > DATEADD(d,-1,GETDATE()) but that gave a nondescript error ... wasn't sure how that would be possible.

Is there some other way to accomplish this?

Then finally, if there is a way to do this, should I expect the stats to be wildly wrong in my situation, and would that affect my query performance?

My concern about the stats comes from this article.

I'm trying to propagate changes from one system to another with some disconnected data ... if you'd like to suggest a completely alternate approach to polling "DateModified", I'd be happy to consider it.

4

1 回答 1

7

不久前有类似的要求,发现过滤器中不允许使用功能。

您可以做的是编写索引并安排它在非高峰(可能是夜间)时间在作业中运行。这也将解决统计问题,因为每次创建索引时都会重新创建它们。

这是我们最终做的一个例子:

    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);
于 2013-09-06T00:01:18.023 回答