2010-12-14 21 views
0

私は、アプリケーションを見ているユーザにとって役に立たない部分的なデータを含むテーブルを持っています。視聴者は、すべての値が計算された同様のテーブルを見たいと思っており、THATデータをすばやく照会できるようにしたいと考えています。通常、これはビューを使用するのに最適な場所です。残念ながら、計算の複雑な性質は私のビューの使用を制限するので、別の解決策が必要です。私は次のようなことを考えていました...複雑なデータを表示する代わりに?

表Aにはバックエンドデータが含まれています。このテーブルが更新されるたびに、これらの計算の結果を示すテーブルBを更新するトリガが発生します。この時点で表Bを迅速に照会することができます。

私の唯一の懸念は、計算手順がやや長く、テーブルAがバーストで何度も更新される可能性があることです。 「Before Select」トリガーに近いソリューションはありますか?だから基本的にテーブルAは何度も何度も更新できますが、テーブルBがクエリされたときにだけ計算が行われますか?

ここでは例のタイムラインです:

  1. 表Aが
  2. 表Aは、データを表Bから要求される
  3. [誰もまだ表Bのデータを必要としないので、SPを実行しないでください]再び更新されて更新されます[実行SPを取得する前に表Bを更新するデータ]
  4. 表Aが更新される
  5. データ
  6. 01 [データを取得する前に、表Bを更新するために実行SP表Bから要求さデータは、だから私の質問はあり

[表A、表Bのデータの要求の間更新されなかったため、ストアドプロシージャを実行しないでください]表Bから要求されます。

  1. のように、既存のものはあります私が上で説明したものは?
  2. もしそうでなければ、更新/挿入のバッチが完了するまでトリガーを止めさせる方法がありますか?表Aは頻繁に変更されないため、更新されると遅いトリガーで暮らすことができます。唯一の問題は、表A に更新されると、通常は一度に数百行になり、毎回遅いトリガーを実行したくないということです。

ありがとうございました!

編集 - なぜにもう少し詳しくは、(私は、少なくとも考える)トリガーの実装は遅いだろう:更新/挿入/削除文を送付します

  1. アプリケーションをLINQツーを使用していますSQLは、バッチ操作ではあまりよくありません。だから、たくさんのレコードを削除したいのであれば、バッチ削除ステートメントの代わりに一連のdeleteステートメントを送ります。削除文をグループ化し、その後にトリガを実行する方法はありますか? (たぶん私はここで話題から離れすぎている)。
  2. 私が言いたいのは、いくつかの再帰関数といくつかの意思決定プロセスです。私が実際に扱っているデータは、データのスケジューリングです。したがって、表Aにはスケジュールされた開始がある場合とない場合があるタスクが含まれています。スケジュールされた開始が定義されていない場合は、スケジュールされた開始時間+その先行時間の前のスケジュールからそれを派生させる必要があります。場合によっては、前任者にもその情報がない可能性があります。したがって、結果を見つけるまで掘り続ける再帰的クエリです。それは辛いほど遅くはないが、すべての挿入/更新/削除で実行する必要があった場合、そこに到達するだろう。上記の「テーブルB」は、基本的には同じテーブルですが、すでに計算されたスケジュールされた開始データがあります(テーブルAの更新時に変更する必要があります)。

答えて

2

私はマテリアライズドビューでこれを解決し、かなり速く動くと思います。しかし、OPは「計算」が何であるかを言わず、遅くしか動かない。結果として、ここで最良の選択肢は次のとおりです。

トリガーをメインテーブルAに追加すると、そのトリガーで影響を受ける行のIDを新しい「作業が必要です」テーブルに挿入します。これは計算がまだ行われていないため、オーバーヘッドが非常に少ないです。

x分ごとに実行され、作業の計算を行い、「作業が完了する必要があります」という表をクリアするジョブを作成します。この仕事は、最終回答を持つテーブルBを作成して同期させるでしょう。

このプロシージャでは、ストアド・プロシージャ・コールを介してのみ「問合せ」にアクセスできます(表Bのデータが最新であることが確認されます)。あなたがテーブルの両方にDeltaTs/EditTs列を持っていた場合は、...

を可能性が表B.

+0

@KM:私の編集を参照してください...マテリアライズドビューについてはわかりませんでしたが、古くなったデータを残しているようですが(私はデータをかなり最新にする必要があります) "仕事をする必要がある"というアイデアはかなり良いです。私の編集に基づいて他の洞察力を持っていますか? – Ocelot20

+0

のビューが同期することは決してありません。[SQL Server 2005のインデックス付きビューによるパフォーマンスの向上](http://technet.microsoft.com/en-us/library/cc917715.aspx) –

2

トリガは、一度に1つの行ではなく、挿入または更新されたレコードのバッチ全体に対して機能します。

わずか数百の新しいレコードで計算に時間がかかり過ぎる場合は、計算自体にパフォーマンスチューニングが必要な可能性があります。

トリガーで計算を実行すると、それらは各トランザクションの一部であり、別のトランザクションが許可される前に終了し、挿入が遅くなる可能性があります。トリガを適切に記述して、行単位で処理するのではなく、一連のデータを処理する場合は、問題が発生しない可能性があります。何百もの行は、ほとんどの計算を行うための簡単な量です。何百万もの行をバッチで挿入していた場合、他のプロセスを妨害するトリガのパフォーマンスがより懸念されます。

計算を実行するためにprocを作成し、10分ごとに実行するようにスケジュールを設定してから、レポートが呼び出されたときに再度実行するようにスケジュールできます。このようにすれば、事前に事前覚醒の大半を行い、レポート時に新しいレコードの最後の数を捕まえることができます。

私たちに計算のサンプルと潜在的なトリガーを与えてください。私たちはあなたを助けることができます。

個別のトランザクションを1つのグループ・トリガーに実行する場合、バンチをグループ化する方法はありません。おそらく、あなたは一緒に処理するバッチが必要な場合は、これとLINQの使用を止めるべきです。一度に複数のレコードで作業する場合は、通常、セットベースの操作が適しています。

+0

私の編集をご覧ください。 – Ocelot20

0

可能であれば(特定の状況に当てはまらないかもしれませんが)、ビュー/テーブルからの選択ではなく、ストアドプロシージャ呼び出しを介してテーブルBからデータを返すことができます。そのようにして、あなたのプロシージャは、それが特に呼び出されたとき(すなわち、テーブルAが更新された後)にのみ重い持ち上げを行います。

0

を使用してこれは、すでに議論されているものの単純バリエーションです:

戻るクエリデータを経由して両方のテーブルのmax(Deltats)とmax(deltats)をチェックし、必要に応じてテーブルbを更新するストアドプロシージャ。最初にテーブルAを更新した後に選択すると、少しヒットしますが、その後は素早く素早くなります。

関連する問題