0

大規模なデータベースでのレポートクエリを高速化するために、あるテーブルのレコード数を別のテーブルの列として保存するトリガーを作成しています。

これが私がこれまでに得たものです。削除では問題なく動作しますが、挿入でも動作する必要があります。別のトリガーを使用する必要がありますか? また、カーソルの使用は必要ですか、それともより効率的な方法はありますか?

ありがとう!

ALTER TRIGGER [dbo].[updateSourceTotals]
   ON  [dbo].imports
   AFTER INSERT, DELETE
AS 
BEGIN

    SET NOCOUNT ON;

    DECLARE @sourceId int;

    DECLARE deleteCursor CURSOR FOR SELECT DISTINCT sourceId FROM deleted

    OPEN deleteCursor

    FETCH NEXT FROM deleteCursor INTO @sourceId

    WHILE @@FETCH_STATUS = 0
    BEGIN

        UPDATE  sources
        SET     totalImports = (
                    SELECT  COUNT(*) 
                    FROM    imports 
                    WHERE   sourceId = @sourceId
                    )
        WHERE   id = @sourceId

    FETCH NEXT FROM deleteCursor INTO @sourceId
    END

    CLOSE deleteCursor
    DEALLOCATE deleteCursor 

END
GO
4

1 に答える 1

2

本当にトリガー アプローチに設定されている場合 (そして私はお勧めしません)、これは現在のコードのよりシンプルでおそらく高速なバージョンです。

ALTER TRIGGER [dbo].[updateSourceTotals]
   ON  [dbo].imports
   AFTER INSERT, DELETE
AS 
BEGIN

    UPDATE  s
    SET     totalImports = (
                SELECT  COUNT(*) 
                FROM    imports i
                WHERE   i.sourceId = s.Id
                )
    FROM    sources s
    WHERE   s.id IN(SELECT sourceId FROM deleted)

END

INSERTs もカバーしたい場合は、次のようにします。

ALTER TRIGGER [dbo].[updateSourceTotals]
   ON  [dbo].imports
   AFTER INSERT, DELETE
AS 
BEGIN

    UPDATE  s
    SET     totalImports = (
                SELECT  COUNT(*) 
                FROM    imports i
                WHERE   i.sourceId = s.id
                )
    FROM    sources s
    WHERE   s.id IN(
                    SELECT sourceId FROM deleted
                UNION
                    SELECT sourceId FROM inserted
                  )

END

追加のボーナスとして、UPDATEs でも機能するはずです。


明確にするために、カーソルを削除した後でも、トリガーで事前集計を行う際の問題は、リクエストごとにクエリを再計算するのではなく、変更ごとにそれらを再計算していることです。

抽象的に見ても、このような要求を多く実行した場合にのみ勝利となりますが、テーブルをあまり変更しないでください。ただし、アクティブな DBMS サーバーの実際のコンテキストでは、この小さな利点さえもほとんど失います。そのような要求を多数行うと、おそらく非常に効果的にキャッシュされているからです書き込みより効果的です)。

于 2013-05-17T16:50:45.513 に答える