0

システムのパフォーマンス データを保持するテーブルがあります。各レコードは、いくつかの重要なメソッドに対して行われた呼び出しであり、メソッド名、その期間、およびトークンで構成されています。システムへの各要求には一意のトークンが与えられるため、すべての同じトークンを持つレコードは同じリクエストです。例:

CallName    Duration    Token
----------- ----------- -----------
GetData     121         12345
Process     800         12345
SaveData    87          12345

GetData     97          ABCDE
Process     652         ABCDE
SaveData    101         ABCDE

Token と CallName でグループ化された集計データに興味があります。たとえば、次のようになります。

-- The total duration of each request, in descending order
SELECT Token, SUM(Duration) FROM Requests GROUP BY Token ORDER BY SUM(Duration) DESC

-- The average duration of each call, in descending order
SELECT CallName, AVG(Duration) FROM Requests GROUP BY CallName ORDER BY AVG(Duration) DESC

現在、このテーブルは非常に大きくなる可能性があり、各クエリの上位数レコードのみに関心があるため、これらのクエリの両方にページングを実装しました。問題は、これらのクエリには集計関数が含まれているため、SQL サーバーが最終的にテーブル スキャンを実行することです。

確かに他の人は以前にこの問題を抱えていましたか?

ここで本当に必要なのは、トークンでグループ化された SUM(Duration) の「インデックス」です。つまり、次のようなことができるテーブルです。

SELECT Token, SumToken FROM RequestTokens ORDER BY SumToken DESC
  • これは本当に悪い考えですか?
  • もしそうなら、より良い方法はありますか?
  • これを行う最良の方法は何ですか?INSERT / UPDATE / DELETE (古い値と変更されたデータに基づいて集計値を更新する場所) でトリガーしますか、またはこのテーブルを更新するときに「インデックス」を手動で更新する方がよいでしょうか?

トリガーは私がこれまで思いついた最良の解決策ですが、これがデッドロック/一貫性の悪夢であることはすでにわかっています! :-S

4

3 に答える 3

3

潜在的に集計に基づくビュー、場合によってはインデックス付きビューについてはどうですか。私はインデックス付きビューをあまり使っていませんが、この記事では、AVG() のような複雑な集計でインデックス付きビューを使用する方法について説明します。多分それはあなたを正しい方向に導くでしょう。

http://msdn.microsoft.com/en-us/library/aa933148%28SQL.80%29.aspx

于 2009-09-21T14:01:04.740 に答える
0

まず、トークン列のインデックスで十分ではないでしょうか? そのようにして、Token 値を指定すると、SQL クエリ オプティマイザーは、関心のある行を含むインデックスのその部分だけをスキャンします。これをクラスター化インデックスにすると、最適なパフォーマンスが得られます。

次に、どのトークン値を集計することに関心があるかをどのように知るのでしょうか? リストされているdatetime(またはtimestamp)列はなく、トークン値はランダムに割り当てられているように見える(何らかの形式の昇順値とは対照的に)ので、クエリを発行する前にトークン値が集計されることを知っていると思います-- 必要なインデックス作成を行う場所。値が不明であるが何らかの理由で昇順である場合、最初に最新の X トークン値を特定するために使用できるいくつかの戦術があり、その/それらのトークンを取得したら、部分的なテーブル スキャンに戻ります。

于 2009-09-21T13:49:55.313 に答える
0

よく理解できたので、これをもう一度突き刺します。これは、データ ウェアハウジング ソリューションにつながる、珍しいレポートの問題ではありません。たとえば、事前に集計されたデータを含む 2 つ目のテーブルを追加することはできますか? これは確かに非正規化/冗長データです...しかし、明確で明確に定義されているように見え、ビジネスのニーズに応えます。このアイデアに関するいくつかのしわ:

データが 1 回だけ入力される場合、データ入力ルーチンを変更して、集計された行を同時に追加できますか。時間の経過とともに細流化する場合は、「物事を一掃する」ために繰り返しプロセスが必要になります。私は一般原則に基づいてトリガーを避けます。ここでは役立つかもしれませんが、使用パターンとデータの相互関係によっては、システムを拘束する可能性もあります。

データはどの程度最新である必要がありますか? 集計データが詳細データと同期していない可能性は? 毎日/毎時/5 分ごとに実行される SQL エージェント ジョブを配置して、最近のエントリをスキャンし、集計テーブルを更新することができます。(インデックス付きの「最後に入力された」列を追加すると、これらの更新が迅速になる可能性があります。)トレードオフは、データがオフになる期間です。(しかし、その datetime 列は、データが「いつまで」正確であるかを示している可能性があります。おそらく、その時点以降の集計データを利用可能にしないでしょうか?)

入力されたデータが変更されない場合 (更新、削除、遅れて到着する行がない場合)、これは機能しますが、長期間にわたって更新を維持する必要があり、集計されたデータの変更次の場所で利用できる必要がある場合データが入力されると同時に、維持するのは悪夢になる可能性があります。

于 2009-09-22T14:13:35.430 に答える