3

リアルタイムのデータを取得してデータベースに挿入するアプリケーションがあります。1 日 4.5 時間オンラインです。17 のテーブルに 1 秒ごとにデータを挿入します。ユーザーはいつでも、最新の 2 番目のデータと履歴内のいくつかのレコードについて任意のテーブルにクエリを実行できます...

フィードと挿入の処理は、C# コンソール アプリケーションを使用して行われます...

ユーザー要求の処理は、WCF サービスを通じて行われます...

挿入がボトルネックであることがわかりました。ほとんどの時間はそこに費やされます。テーブルと指標を微調整するために多くの時間を費やしましたが、結果は満足のいくものではありませんでした

十分なメモリがあると仮定すると、データベースの代わりにメモリにデータを挿入するベスト プラクティスは何ですか。現在、毎秒更新および挿入されるデータテーブルを使用しています。私たちの同僚は、フィード ハンドラーと WCF ユーザー要求ハンドラーの間のデータベースではなく、別の WCF サービスを提案しました。WCF 中間層は TCP ベースであると想定されており、データを独自のメモリに保持します。フィード ハンドラーは、2 つのプロセス間に中間層を設ける代わりにユーザー リクエストを処理するかもしれないと言うかもしれませんが、フィード ハンドラーがクラッシュした場合でも、現在のレコードをユーザーに提供できるようにするために、物事を分離したいと考えています。

時間は限られていますが、短期間ですべてを記憶に移したいと考えています。2 つのプロセスの途中で WCF を使用するのは悪いことですか? リクエストがオーバーヘッドを追加することはわかっていますが、これら 3 つのプロセス (フィード ハンドラー、メモリ内データベース (WCF)、ユーザー リクエスト ハンドラー (WCF)) はすべて同じマシン上にあり、帯域幅はそれほど多くありません。問題の。

手伝ってください!

4

3 に答える 3

2

データのキャッシュを作成して(データベースの選択を減らすこともできます)、データベースに書き込まれたキャッシュ内のデータを無効にすることを検討します。このようにして、多数の小さな挿入ではなく、より大きな挿入を行う呼び出しをバッチ化できますが、リーダーが読み取れるようにデータをメモリ内に保持できます。実際、データがいつ古くなるかがわかっている場合は、データベース全体を読み取ることを避けて、それをバッキング ストアとして使用することができます。この方法では、データベースのパフォーマンスはキャッシュのサイズにのみ影響します。

キャッシュ内のデータの無効化は、データがデータベースに書き込まれたか、古くなったかのいずれかに基づいて、最初ではなく最後に行われます。

キャッシュ層は複雑である必要はありませんが、データをホストし、バックグラウンドで保存するためにマルチスレッド化する必要があります。このレイヤーは、WCF サービス (接続媒体) のすぐ後ろに位置し、コンソール アプリのロジック + バッチ処理のアイデアを含むように WCF サービスを改善する必要があります。その後、コンソール アプリは WCF に接続して結果をスローするだけです。

更新:他に言えることは、プロファイラーに投資して、マスクされているコードにパフォーマンスの問題が発生しているかどうかを確認することです。また、データベースをプロファイリングします。高速な挿入と選択が必要だとおっしゃいましたが、残念ながら、それらは通常互いにトレードオフの関係にあります...

于 2010-07-05T10:22:50.160 に答える
0

どのようなデータベースを使用していますか? MySQL には、この種のことに適していると思われるストレージ エンジン MEMORY があります。

于 2010-07-05T10:14:30.170 に答える
0

DataAdapter で DataTable を使用していますか? もしそうなら、それらを完全に削除することをお勧めします。DBCommand を使用してレコードを直接挿入します。ユーザーがレポートを要求すると、DataReader を使用してデータを読み取るか、DataTable.Load (IDataReader) を使用して DataTable オブジェクトを設定します。

メモリ内のデータをストーリー化すると、クラッシュや電源障害が発生した場合にデータが失われるリスクがあります。

于 2010-07-05T10:20:31.457 に答える