この質問に答えるのは少し難しいです。なぜなら、私たちはあなたの要件をすべて知っているわけではなく、何かが以前はうまくいかなかったからです。そこで、ここにいくつかの異なるアイデアがあります。
まず、あなたの仮定を再検討してください。日次レポートだけが必要な場合、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 を使用してファンシーを追加できます。