4

私はSQL Server 2008-R2を使用していますが、より一般的な回答にも興味があります...

何億行ものテーブルがあり、それぞれに「DateModified」フィールドがあります (datetime2(7))

今、私は非常に頻繁にそのテーブルを次のようなクエリでポーリングします

select * from table where DateModified > @P1 

ここで、パラメーターは常に最新 (過去数分以内など) であり、その値に一致するレコードはおそらく少数です。

これらの値の多くにインデックスを使用することは決してないのに、テーブル全体に大きなインデックスを維持していることに気づきました...したがって、これは、フィルター処理されたインデックスの完全な使用のように聞こえます。に対してクエリを実行する可能性があります...

しかし、この場合、フィルターはどのように見えるでしょうか? 私の唯一のアイデアは、フィルターをかけることでした

where DateModified > [yesterday]

where[yesterday]は日付リテラルですが、フィルターを定期的に再定義する必要があります。そうしないと、フィルターの利点が時間の経過とともに減少します。

気まぐれに試しModifiedDate > DATEADD(d,-1,GETDATE())てみましたが、説明のつかないエラーが発生しました...どうすればそれが可能になるのかわかりませんでした。

これを達成する他の方法はありますか?

最後に、これを行う方法がある場合、私の状況では統計が大幅に間違っていると予想する必要がありますか?それはクエリのパフォーマンスに影響しますか?

統計に関する私の懸念は、この記事から来ています。

切断されたデータを使用して、あるシステムから別のシステムに変更を伝達しようとしています...「DateModified」をポーリングするための完全に別のアプローチを提案したい場合は、喜んで検討します。

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 に答える