これを行うための最速の方法は何ですか:
- 1 つのテーブル、事前に入力できない参照はありません (つまり、参照キーが 1 つありますが、すべてのデータが入力されています)。
- たくさんのデータ。APIを介して動的に入力される、1日あたり数億行について話します
- 要求は、ほぼリアルタイムのシナリオで可能な限り早く処理する必要があります (つまり、1 日 1 回のアップロードのためにファイルに書き出す必要はありません)。2 秒が通常の最大遅延です
- データ/アプリケーションと SQL Server 用に別のマシン
私が今していること:
- 最大 32*1024 行を配列に集約してから、キューに入れます。
- 2 ~ 3 スレッドでキューを読み取ります。SqlBulkCopy を使用してデータベースに挿入します。
1 秒あたり約 60k ~ 75k 行がインポートされますが、これは十分ではありませんが、かなり近い値です。250.000行を達成したいと思っています。
これまでのところ、実際には何も使用されていません。私は 20% の時間「ネットワーク I/O」ブロックを取得し、1 つのコアで 80% の CPU 側をロードしました。ディスクは 7 mb ~ 14 mb を書き込んでおり、ほとんどアイドル状態です。6 raptors の RAID 10 の平均キュー長は.... 0.25 です。
これをスピードアップする方法を知っている人はいますか?より高速なサーバー (これまでのところ、仮想、8 GB RAM、4 コア、データ用の物理ディスク パス スルー)。
いくつかの説明を追加します:
- これは、2008 R2 サーバー上の 2008 R2 Enterprise SQL Server です。マシンには 4 コア、8 GB RAM があります。すべて64ビット。80% の負荷平均は、約 20% の CPU 負荷を示すこのマシンからのものです。
- テーブルは単純で、主キーはなく、リレーショナル参照 (計測器参照) のインデックスと一意 (一連の計測器内であるため、これは強制されません) タイムスタンプのみです。
- テーブルのフィールドは次のとおりです: タイムスタンプ、インストゥルメント リファレンス (強制的な外部キーなし)、データ タイプ (char 1、投稿されたデータを示す文字数の 1 つ)、価格 (double)、ボリューム (int)。ご覧のとおり、これは非常に薄いテーブルです。問題のデータは、金融商品のティック データです。
- 質問はハードウェアなどについてもです。主に、実際のボトルネックが見られないためです。私は複数のトランザクションに挿入していますが、それは私に利益をもたらしますが、それは小さなものです。ディスク、CPU は大きな負荷を示しておらず、ネットワーク io 待機は高くなっています (300 ミリ秒/秒、現時点では 30%) が、これは 2 つのサーバーで JSUT を実行し、すべてを実行するのに十分なコアを備えた同じ仮想化プラットフォーム上にあります。私は「別のサーバーを購入する」ことにほとんどオープンですが、最初にボトルネックを特定したいと思います....特に、結局のところ、ボトルネックが何であるかを把握していないことを考えると. ロギングは関係ありません。一括挿入はデータとしてデータ ログに記録されません (クラスター化されたインデックスはありません)。
たとえば、バイト (tinyint) によって、たとえば 16 個のテーブルでインストゥルメント ユニバースを分割し、同時に最大 16 個の挿入を行うことで、垂直分割が役立ちますか? 実際には、データはさまざまな取引所から取得されるため、取引所ごとにパーティションを作成できます。これは自然な分割フィールドになります (これは実際には計測器にありますが、ここでこのデータを複製することができます)。
いくつかの明確化: 速度がさらに高速になり (90k)、マシン間のネットワーク IO によって明らかに制限されました。これは VM の切り替えである可能性があります。
私が今していることは、32k行ごとに接続を行い、一時テーブルを作成し、SqlBUlkdCopyでこれに挿入し、次に1つのSQLステートメントを使用してメインテーブルにコピーすることです-メインテーブルのロック時間を最小限に抑えます.
現在、ほとんどの待機時間はネットワーク IO にあります。VMが賢明な問題に遭遇したようです。今後数か月で物理ハードウェアに移行します ;)