超高速データベースで10億行をスキャン


9

バックグラウンド

ローカルデータベースには、約13億の一意の行が含まれています。各行は、特定の緯度と経度(場所)に間接的に関連付けられています。各行には日付スタンプがあります。

使用事例

問題は次のとおりです。

  1. ユーザーは、開始/終了日と値の範囲(たとえば、100から105)を設定します。
  2. システムは、特定の日付に一致するすべての行を、場所ごとにグループ化して収集します。
  3. システムは、これらの日付の間に、指定された値の範囲に該当する可能性がある場所を決定します。
  4. システムは、一致するすべての場所をユーザーに表示します。

これは速度と規模の問題です。

質問

そのようなシステムが5秒未満でユーザーの結果を取得できると想像できる最も安価なソリューションアーキテクチャは何ですか。

現在のシステム

現在の環境は次のとおりです。

  • PostgreSQL 8.4(アップグレードは可能です。データベースの切り替えはオプションではありません)
  • RおよびPL / R
  • XFS
  • WD VelociRaptor
  • 8 GB RAM(Corsair G.Skill; 1.3 GHz)
  • クアッドコア本物のインテル7(2.8 GHz)
  • Ubuntu 10.10

ハードウェアのアップグレードは許容されます。

更新-データベース構造

数十億行が次のようなテーブルにあります。

id | taken | location_id | category | value1 | value2 | value3
  • id-主キー
  • 取られた-行に割り当てられた日付
  • location_id-緯度/経度への参照
  • カテゴリ-データの説明
  • value1 .. 3-ユーザーがクエリできるその他の値

takenカラムは、典型的にはあたり連続日付でlocation_id時々各位置1800から2010年までのデータを有し、(各位置は、同じ日付範囲のデータを有するよう77,000約日付が、それらの多くが重複)。

7つのカテゴリがあり、テーブルはすでにカテゴリ別に分割されています(子テーブルを使用)。各カテゴリには、1億9000万行が含まれます。近い将来、カテゴリごとの行数は10億を超えるでしょう。

約20,000の場所と70,000の都市があります。場所は、緯度と経度によって都市に関連付けられています。各場所を特定の都市に割り当てることは、都市の境界を見つけることを意味しますが、これは簡単な作業ではありません。

アイデア

私が持っているいくつかのアイデア:

  • データベースをホストするクラウドサービスを見つけます。
  • SSD RAIDストライプを作成します(素晴らしいビデオ)。
  • 都市ごとにすべての場所を統合するテーブルを作成します(事前計算)。

ありがとうございました!


10
「データベースの切り替えはオプションではありません」ということは、ほとんどのソリューションをほとんど排除します。幸運を!
Steven A. Lowe、

1
これらのレコードを使用して正確に何をしているのかについての詳細な情報がないと言うのは難しいです。また、5秒間の最悪のケースを探していますか?
Guy Sirton、2011年

2
@デイブ:現在のシステムはどのくらい時間がかかりますか?現在のシステムはPostGISを使用していますか?であるか、または第二のテーブルを参照しますか?列にインデックスが付けられていますか?location_idgeographygeometrylocation_id
rwong

1
@Thorbjørn&@Darknight-アイデアセクションで、事前計算をリストします。これにより、データが都市ごとに(カテゴリごとに)1日あたり1つの値に削減されます。計算は毎年または毎月繰り返される可能性があると思います。他の可能性がない場合、これは私の計画でした(計算にはおそらく数週間かかります)。
デイブジャービス、

1
@Dave、たくさんの可能性がありますが、問題はあなたに何が関連しているかです。現在のボトルネックがどこにあるかを調査しましたか?

回答:


12

最も重要なことは、データベースを切り替えることができないため、ボトルネックが特定の数の代表的なリクエストに今どこにあるのかを確実に特定することです。

全表スキャンを行う場合は、適切なインデックスが必要です。

I / Oで待機する場合は、キャッシュ用により多くのメモリが必要です(Jeff Atwoodは最近、24 Gbシステムはデスクトップシステムで到達可能であると述べました)。

CPUで待機する場合は、計算を最適化できるかどうかを確認する必要があります。

これには、先​​のとがったDBAハットとオペレーティングシステムハットが必要ですが、適切なツリーを確実に起動するためには価値があります。


どのようにスライスしてダイシングするか-各行に100バイトしかかからない場合でも、13億行= 121 GB。あなたのすべてのインデックスなどで、これははるかに多くなると確信しています。単一のボックスでは、SSD +トンのRAMに関するいくつかの深刻なハードウェアがない限り、遅くなるでしょう。安価な方法は、ボックス間でスケーリングすることです。
Subu Sankara Subramanian '25年

4
@スブ、あなたは配布したいですか?今、あなたには2つの問題があります...

へー-私は同意します:)しかし、それはより安いです!
Subu Sankara Subramanian '25年

@Thorbjørn:お時間をいただきありがとうございました。データセットをカテゴリごとに2,500万行に減らし、日付にインデックスを適用すると思います。これにより、スキャンが〜70000行に削減され(範囲は2週間に制限されます)、かなり高速になります。
Dave Jarvis、

@デイブ、あなたはまだあなたのボトルネックがどこにあるかを知る必要があります。あなたがする必要はありません、それを学びます。

4

日付スタンプに基づいて、テーブルを異なるホストにある複数の部分に分割してみませんか?これは水平方向にスケーラブルであり、十分な数のボックスがある限り、これらのセットアップの上に小さな集約エンジンを書くことができます。

日付スタンプの変化が大きすぎる場合は、場所に基づいてパーティション分割できます。これも水平方向にスケーラブルです。(うまくいけば、彼らは緯度/経度の多くを追加しないでください!)


アイデアをありがとう。潜在的に77,066の日付があり、今後新しい日付が追加されます。私は1台のマシンを持っています。20,000か所の場所がありますが、分析するデータはすべての場所にまたがっているため、場所ごとに分割しても役に立ちません。
デイブジャービス、

クラウドの使用は上記のソリューションとどのように異なりますか?
チャニー

私もそう思いました。検索がすべてのパーティション間で並行して行われるように、ある種の水平パーティション。
davidk01 '25年

その日に分割するのがおそらく最も役立つでしょう。その結果、2562の個別のテーブル(366日x 7カテゴリ)が作成されます。
Dave Jarvis、

4

最悪のシナリオは、日付範囲がデータベース内のすべての日付をカバーすることです。

13億件のレコードを読み取り、5秒未満で、1台の物理マシン上で、各レコードと入力された値に対して何らかの分析を行っているとします。結果は、すべての場所である場合も、まったくない場合もあります。事前に何もわかっていません。

これらのパラメータを考えると、おそらく不可能だと思います。

ハードドライブを見てください。最大持続レートは150MB / s未満です。13億件のレコードを読み取るには5秒以上かかります。CPUに関しては、5秒間で13億件のレコードを統計的に分析することはできません。

あなたの唯一の望み(tm :-))は、ユーザーが入力した値に基づいて、検索を(数桁)絞り込む絞り込み関数を見つけることです。このルックアップ関数はオフラインで計算できます。正確な一致基準について詳しく知らなければ、誰もそれを行う方法を教えられるとは思いませんが、例としては、値の範囲をいくつかの個別の間隔に分割し、その間隔のすべてのレコードを提供するルックアップを作成することです。間隔が十分に短い限り、実際の作業を行うことができます。たとえば、ユーザーが入力した値と一致しないエントリを削除します。基本的に時間とスペースを交換します。

メモリ内のすべてのレコード(または少なくとも重要な部分)を保持することが可能な場合があります。おそらく8GBではありません。これにより、少なくともディスクI / O部分がなくなりますが、メモリ帯域幅でさえ、5秒ですべてをスキャンするには不十分な場合があります。とにかく、これはこの種のアプリケーションを高速化するためのもう1つの手法です(以前の提案と組み合わせる)。

クラウドサービスの使用について言及します。はい、十分なCPUとIOの筋肉にお金を払い、多くのサーバー間でデータベースを分割すると、総当たり/分割して征服することができます。


答えてくれてありがとう。私が挙げたアイデアによると、ハードウェアのアップグレードは考慮事項です。750米ドル未満のソリューションが理想的です。
Dave Jarvis、

2

質問に対するrwongのコメントの2番目:PostgreSQLは、適切なインデックスタイプとツール(GISTインデックス、GINインデックス、Postgis、Geometricalタイプ)を提供しており、ジオデータと日時関連データは、それほど問題なくこれらの基準に沿って検索できるはずです。

これらの基準でのクエリに数秒かかる場合は、そのようなインデックスが使用されていないことを意味します。これらを適切に調査したことを確認できますか?


ありがとうございました。7つの子テーブルは、btreeを使用して場所、日付、およびカテゴリでクラスター化されます。私は昨年GINインデックスを調査しましたが、覚えていません。
Dave Jarvis、

2
Bツリーに基づくインデックスの場所は、調査している検索のタイプ​​を考慮すると、少し役立つものではありません。必要な演算子と連動する逆インデックスが必要です。これは、Postgisの場合、通常GISTを意味します。遅いクエリのいくつかを強調したいと思うかもしれません...
Denis de Bernardy

1

PostgreSQLと緯度/経度データを使用する場合は、必ずPostGISも使用する必要があります。これにより、GiST空間インデックスをデータベースに追加して、高速化を図ることができます。

私はそのようなテーブル(350k行)を持っていますが、あなたの設定(2コアとかろうじて2Gb RAM)よりもはるかに小さい構成ですが、検索にかかる時間は1秒未満です。


0

EssbaseがOLAPアーキテクチャで行ったようなリレーショナルモデルを破ることができるかもしれません: Essbaseウィキペディア

つまり、都市ごとに1つのテーブルを作成し、最終的に1000以上のテーブルを作成します。あなたが提案したような1つのテーブルではなく、多く。日付と場所で各テーブルにインデックスを付けます。多くのテーブル、多くのインデックス->より高速。


メモありがとうございます。70,000を超える都市があり、多くの異なる緯度/経度の値が特定の都市エリア内にあります。
Dave Jarvis、

@Dave:都市のボロノイ図を作成し、緯度/経度の値をテッセレーションに分類できますか?(つまり、それが無計画に聞こえる場合は、それを許可します。)次に、ルックアップ中に、テッセレーションがクエリの緯度/経度の範囲に接するすべての都市を検索します。ボロノイテッセレーションが遅すぎる場合は、正方形のボックス(たとえば、緯度5度x経度5度)を試す価値があります。
rwong

0

データベースをホストするクラウドサービスを見つけるというアイデアに関して、SimpleGeoに出会ったことはありますか?10億を超える行の保存とクエリにかかるコストにより、このアプローチは実行不可能になる可能性がありますが、明らかに「場所データの保存とクエリを実際に非常に高速に行うように特に調整されている」ストレージサービスのリボンを切りました。


-2

あなたは自転車が高速道路を走ることを期待しています。現在、この問題に取り組むためのソリューションを探していますが、20億件のレコードがある場合、問題を予測できません。スケーラビリティに対処する必要があります。答えはオブジェクトデータベースの簡単な使用です。例:システム間キャッシュ

そして、私がシステム間出身ではないことを信じてください;-)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.