0

これが問題です。

私が最近乗っ取ったサイトでは、あなたが 1 日に走った「マイル」を記録しています。したがって、ユーザーはサイトにログインして、5 マイル走ったことを追加できます。次に、これがデータベースに追加されます。

1 日の終わりの午前 1 時頃に、すべてのマイルを計算するサービスが実行され、その日にすべてのユーザーが走行し、テキスト ファイルが App_Data に出力されます。そのテキスト ファイルは、ホームページ上でフラッシュ表示されます。

これはちょっとばかげていると思います。大規模なパフォーマンスの問題のために、これを行う必要があると言われました。以前はどのようにしていたのか、パフォーマンス上の大きな問題は何だったのかについては、正確には教えてくれません。

では、皆さんはどのようなアプローチをとりますか?最初に頭に浮かんだのは、AJAX 呼び出しを介してデータを取得する Web サービスでした。おそらく、新しい「マイル」エントリが追加されるたびに、トリガーが起動され、「GlobalMiles」テーブルが更新されます。

これに関する情報やヒントをいただければ幸いです。

本当にありがとう!

4

3 に答える 3

1

この質問に答えるのは少し難しいです。なぜなら、私たちはあなたの要件をすべて知っているわけではなく、何かが以前はうまくいかなかったからです。そこで、ここにいくつかの異なるアイデアがあります。

まず、あなたの仮定を再検討してください。日次レポートだけが必要な場合、1 日 1 回静的レポートを生成することは完全に有効なソリューションです。必要なのはスナップショットだけなのに、1 日に何回もデータベースにアクセスする必要はありません (たとえば、多くのブログ ソフトウェアは、毎回データベースからエントリを提供するのではなく、ブログが投稿されたときに html ファイルを書き込むために使用されます。多くのブログ ソフトウェアは今でもそうしています)。最適化として)。「リアルタイム」機能はあなたが追加しようとしているものですか?

私はすぐに AJAX に飛びつくつもりはありません。同じ入力方法を使用して、レポートを静的から動的に移動するだけです。一度に多くのことを行うのは、自分を埋没させる良い方法です。既存のコードを変更するときは、アプリケーションの残りの部分への影響を最小限に抑えて、単独で変更できる領域を見つけようとします。次に、動的レポートを作成したら、AJAX を追加できます (プログレッシブ エンハンスメントを使用してください)。

動的レポート自体に関しては、いくつかのオプションがあります。

もちろん、SELECT SUM() だけでもかまいませんが、各ユーザーが多数のエントリを持っている場合、パフォーマンスの問題が発生するようです。

データベースがサポートしている場合は、インデックス付きビュー(マテリアライズド ビューと呼ばれることもあります) の使用を検討します。リアルタイム合計データの高速更新をサポートする必要があります。

CREATE VIEW vw_Miles WITH SCHEMABINDING AS 
SELECT SUM([Count]) AS TotalMiles, 
COUNT_BIG(*) AS [EntryCount],
UserId
FROM Miles
GROUP BY UserID
GO
CREATE UNIQUE CLUSTERED INDEX ix_Miles ON vw_Miles(UserId)

そのオーバーヘッドが大きすぎる場合は、@ jn29098 の解決策が優れています。スケジュールされたタスクを使用してロールアップします。各ユーザーに多数のエントリがある場合は、タスクが最後に実行されたときからのデルタしか追加できませんでした。

UPDATE GlobalMiles SET [TotalMiles] = [TotalMiles] + 
  (SELECT SUM([Count]) 
    FROM Miles 
    WHERE UserId = @id 
      AND EntryDate > @lastTaskRun
    GROUP BY UserId)
WHERE UserId = @id

個々のエントリを保存する必要がなく、合計のみを保存する場合は、その場でカウントを更新できます。

UPDATE Miles SET [Count] = [Count] + @newCount WHERE UserId = @id

このメソッドを、エントリを追加して両方の世界を持つ SPROC と組み合わせて使用​​できます。

最後に、トリガー メソッドも同様に機能します。これは、SQL を自動的に更新するのではなく、自分でテーブルを更新するインデックス付きビューの代替手段です。これは、グローバル更新を sproc からトリガーに移動する前のオプションにも似ています。

最後の 3 つのオプションを使用すると、エントリが削除されたときの状況を処理するのが難しくなりますが、それがアプリケーションの機能でない場合は、心配する必要はないかもしれません。

データベースに実体化されたリアルタイム データを取得したので、レポートを動的に生成できます。次に、AJAX を使用してファンシーを追加できます。

于 2009-07-02T03:16:21.403 に答える
1

総走行距離を計算する、1 時間または毎晩 1 回ロールアップされる集計テーブルを作成します。個々のリクエストについては、毎晩のサマリー テーブルと、最後のロールアップ計算からユーザーがページを表示してそのユーザーの合計を取得するまでの期間に記録された追加のマイルから引き出すことができます。

何人のユーザーのことで、1 日あたりのログ レコードの数は?

于 2009-07-02T02:55:33.067 に答える
1

データベースへの多数のヒットが原因でパフォーマンスの問題が実際に発生している場合は、すべての入力を取得してメッセージ キュー (MSMQ) に詰め込むことをお勧めします。次に、メッセージを取得してデータの一括挿入を行うサービスをもう一方の端に配置できます。これにより、db ヒットが少なくなります。その後、更新時にテキスト ファイルに出力することもできます。

于 2009-07-02T02:40:55.827 に答える