web-dev-qa-db-ja.com

合計数十億行と毎日数百万行の挿入:どのデータベースシステムが最適か

データ量は非常に多いが、データ構造は非常に単純化されたシステムを開発しました。 cellXcellYtimeStampvalue列のみがありました。

操作は次のとおりです。

  • 1日あたり455+千行を挿入
  • cellXcellY、およびtimeStampの範囲フィルターを使用したクエリ
  • クエリは即座に戻る必要はありません。要求されたデータの準備ができたらユーザーに通知できます。

データが大きすぎてクエリにインデックスが必要なため、次のスキームを使用しました。

  1. SQL Serverを使用します。
  2. cellXcellYtimeStampのクラスター化インデックス。
  3. 毎年別々のテーブルであるため、テーブル内の行の総数は制限内にあります(〜1億6,600万)。
  4. timeStampにはカスタム形式を使用します。年をスキップし、月、日付、時間のみを保持します。 16ビットint以内に保つことができました。
  5. 各年のテーブルで partition を使用します。
  6. 一度に1日のデータを挿入します。 パーティションの切り替え を使用して、データを挿入している間、データベースをライブに保ちます。

これは今のところうまく機能しています。データの準備ができたらユーザーに通知しますが、クエリが適切である限り、遅延は数秒以下です。
しかし、最近、より正確なデータを取得する機会を得て、データ量が68倍に増加しました!。したがって、次のようになります。

  • 1日あたり3,000万行以上行挿入します。
  • テーブルに1年間110億行を格納します。これは、四半期ごと(27億)または毎月(10億にすることで削減できます。 -))テーブル。

これにより、1〜2年でより正確なデータを受け取ることができる可能性があります。そのため、データ量が大幅に増加する可能性があります。

問題は、この方式で持続を使用するかどうかです。または、別のスキームに移行する必要があります。SQLServerを離れる別のデータベースシステムである可能性がありますか?


編集する

3次元の列cellXcellYおよびtimeStampは、本質的に非常に規則的です。これらのすべてをf(x) = mx + cで定義できます。ある整数xレンジング(0, 1, 2, ..., X)。

5
Mohayemin

私は、ページ圧縮と10年の歴史を持つ、300億以上の月次パーティションテーブルを使用してきました。テーブルスキーマは、varchar列と2つの非インデックス列にdatetime2(2)のクラスター化インデックスと3つの非クラスター化インデックスがあり、かなりシンプルでした。ストレージは約2TBで、かなり良好に機能しました。 SqlBulkCopyは、ほぼリアルタイムでデータが必要なため、1日を通して約1500万行を継続的に挿入するために使用されました。

この逸話に基づいて、適切なサイズのハードウェアでSQL Serverが予想されるボリュームを処理できると確信しています。とはいえ、あなたのアプリケーションは遅延に対する耐性があるため、コストのかからないNoSQLソリューションの優れた候補であるという@DamianoVerzulliに完全に同意します。

6
Dan Guzman

そのクラスター化インデックスの断片化が急速に進んでいませんか?これは挿入と選択に悪影響を及ぼします。

別のインデックスを検討する
毎日データを読み込んでいます-当日または前日と想定します
PK cellX、cellY、timeStamp
それが最大の断片化です

検討する
PK timeStamp、cellX、cellY
そして、その順序でソートされたデータをロードします
並べ替えのためにステージングテーブルにロードする必要がある場合でも
これが最小の断片化です

クエリのパフォーマンスのために本当にcellX、cellYインデックスが必要な場合は、フィルファクタ<1の別のパーティションの別のインデックスにそれを配置し、インデックスのメンテナンスを実行します。これが営業時間外に行われる場合は、インデックスを無効にして挿入し、インデックスを再構築する方が速い場合があります(この場合、FILL FACTORまたは1を使用できます)。

1
paparazzo