質問

SQL Server 2005データベースに対していくつかのカスタムレポートを作成しています。データベースは、私たちが実行するサードパーティ管理アプリケーションに属します。私がプルしているデータは、サイトの主要な目的ではないため、データはタイムスタンプ列を除いてほとんどインデックスされていません。今のところ、関係するテーブルは1つだけです。これは、約7億行のテーブルです。したがって、50行しか返さないでください。

私はこれをスピードアップしようとしていますが、私がWhere句に追加するすべての列のインデックスを付けたくない - 私は多くのインデックスが速度を大幅に改善することになることを追加することはわかりません(または私は私は私です間違い?)。だから私は私がベストプラクティスがどうなるか興味があります できませんでした 新しいインデックスをテーブルに追加してください!

ストアドプロシージャは最適ではないようです。インデックス付きビューが最良のアイデアかもしれませんか?考え?

これがテーブルスキーマです:

DeviceGuid (PK, uniqueidentifier, not null)
DeviceID (int, not null)
WindowsEventID (PK, int, not null) (indexed)
EventLog (varchar(64), not null)
EventSource (varchar(64), not null)
EventID (int, not null)
Severity (int, not null)
Description (nvarchar(max), not null)
TimeOfEvent (PK, datetime, not null) (indexed)
OccurrenceNbr (int, not null)

これがサンプルクエリです:

SELECT COUNT(*) AS NumOcc, EventID, EventLog, EventSource, Severity, TimeOfEvent, Description
FROM WindowsEvent
WHERE DeviceID='34818'
    AND Severity=1
    AND TimeOfEvent >= DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), '2010/10/27 12:00:00 AM')
    AND TimeOfEvent <= DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), '2010/11/3 12:00:00 AM')
    AND EventID<>34113
    AND EventID<>34114
    AND EventID<>34112
    AND EventID<>57755
    AND EventSource<>'AutoImportSvc.exe'
    AND EventLog='Application'
GROUP BY EventID, EventLog, EventSource, Severity, Description
ORDER BY NumOcc DESC

たぶん、クエリは吸う...それは4.5分で53列を返します。

役に立ちましたか?

解決 3

ここでの最後の解決策は、インデックス化されたフィールドに対してクエリを実行し、クエリを実行するアプリケーション内でそれらをフィルタリングすることでした。 2つのフィールドは、1つのインデックスに対してクエリをして、必要なデータの非常に近い近似を取得できるほど十分な十分な情報を含むことになりました。ループバックして、結果リストから非マッチングエンティティを削除しました。時間がかかりました!

他のヒント

クエリがインデックスを使用していない場合、それは本当に悪いでしょう。すべての列にインデックスは必要ありませんが、右の列にそれが必要です。 Timeofeventがすでにインデックスされていることを考えると、それはあなたのニーズに合ったものではないかもしれません。

右の列は、データの分布に依存します。最良のインデックスは、おそらく最高の選択性を提供するインデックスです(つまり、インデックスの重要な値を知っている場合、最も少ない行を返します)。最高の選択性を提供する列を知っている場合は、そのインデックスを試すことができます。

最適なインデックスを決定するために、SSMSの表示推定実行計画を使用できます。これにより、どのインデックスが使用されるかを確認するのに役立ちます。インデックスを追加した後、クエリを実行して、実行計画で結果を評価できます。そして、もちろん、経過時間を観察することも役立ちます。

Double Row_Numberトリックを使用してこの方法を試してください:

SELECT  RN_Desc as NumOcc, *
FROM    (
        SELECT  row_number() Over(partition by EventId order by EventLog, EventSource, Severity, Description) as RN_Asc,
                row_number() Over(partition by EventId order by EventLog desc, EventSource desc, Severity desc, Description desc) as RN_Desc,
                *
        FROM    WindowsEvent 
        WHERE   DeviceID='34818' 
                AND Severity=1 
                AND TimeOfEvent >= DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), '2010/10/27 12:00:00 AM') 
                AND TimeOfEvent <= DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), '2010/11/3 12:00:00 AM') 
                AND EventID<>34113 
                AND EventID<>34114 
                AND EventID<>34112 
                AND EventID<>57755 
                AND EventSource<>'AutoImportSvc.exe' 
                AND EventLog='Application' 
        ) t
WHERE   RN_Asc = 1 
ORDER BY NumOcc DESC 

これにより、エンジンはテーブルを単一のパスだけで集約する必要がありません。うまくいかない場合は、正しいグループ化を取得するために、Rownumberの一部で注文を使用してパーティションをかけてみてください。

これは非常に簡単ですが、インデックス付き値を最初のテストとして試してみます

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top