web-dev-qa-db-ja.com

5億を超える行を処理できるデータベース

5億行以上を処理できるデータベースを探しています(妥当な時間で列にインデックスを作成し、3秒以内に選択クエリの結果を提供します)。ローエンドマシン(コア2 CPU 6600、4GB、64ビットシステム、Windows Vista)上のPostgresqlまたはMsqlは、このような多数の行を処理しますか?

更新:この質問をして、where句で指定された1つまたは2つのフィールドを持つ質問を選択するための結果を提供するために、ローエンドマシンで使用するデータベースの情報を探しています。参加しません。選択クエリに対して十分なパフォーマンスを達成するには、インデックスを作成する必要があります(mysqlのように年齢を取ることはできません)。このマシンは、実験を行うためのテストPCです。

テーブルスキーマ:

 create table mapper {
        key VARCHAR(1000),
        attr1 VARCHAR (100),
        attr1 INT,
        attr2 INT,
        value VARCHAR (2000),
        PRIMARY KEY (key),
        INDEX (attr1), 
        INDEX (attr2)   
    }
41
Skarab

MSSQLはその数の行をうまく処理できます。クエリ時間は、単純な行カウントよりもはるかに多くの要因に完全に依存しています。

たとえば、次のものに依存します。

  1. それらのクエリが行う結合の数
  2. インデックスがどれだけうまく設定されているか
  3. マシン内のラムの量
  4. プロセッサの速度と数
  5. ハードドライブの種類とスピンドル速度
  6. 行のサイズ/クエリで返されるデータの量
  7. ネットワークインターフェイスの速度/遅延

クエリを実行するのに数分かかる小さな(10,000行未満)テーブルを作成するのは非常に簡単です。たとえば、多数の結合、where句の関数、およびAtom 512MBの合計RAMを持つプロセッサ)のゼロインデックスを使用します。;)

すべてのインデックスと外部キーの関係が良好であること、クエリが最適化されて不要な関数呼び出しが排除され、実際に必要なデータのみが返されることを確認するには、もう少し作業が必要です。また、高速なハードウェアが必要になります。

要するに、どのくらいのお金を使いたいか、開発チームの質、そしてあなたが扱っているデータ行のサイズに帰着します。

[〜#〜] update [〜#〜]質問の変更による更新。

ここでの情報量は、現実世界の答えを出すにはまだ十分ではありません。それをテストし、必要に応じてデータベース設計とハードウェアを調整するだけです。

たとえば、これらの仕様を持つマシンのテーブルに10億行を簡単に作成し、「select top(1)id from tableA(nolock)」クエリを実行して、ミリ秒単位で答えを取得できます。同じトークンで、「select * from tablea」クエリを実行できます。クエリは迅速に実行されますが、そのデータをすべてワイヤ経由で転送するには時間がかかるため、時間がかかります。

ポイントは、テストする必要があるということです。つまり、サーバーをセットアップし、いくつかのテーブルを作成して、それらを設定します。次に、パフォーマンスチューニングを行って、クエリとインデックスを正しく設定する必要があります。パフォーマンスチューニングの一環として、クエリの再構成方法だけでなく、ロックに基づいてマシンのどの部分を交換する必要があるか(つまり、ディスク、RAM、CPUなど)を明らかにします。および待機タイプ。

これを行うには、1人または2人のDBAを雇う(または契約する)ことを強くお勧めします。

51
NotMe

ほとんどのデータベースはこれを処理できます。これは、このデータをどのように処理するか、およびどのように処理するかに関するものです。多くのRAMが役立ちます。

私はPostgreSQLから始めます。これは無料で、RAM(SQL Server Expressとは異なります)に制限はなく、ライセンスに潜在的な問題はありません(プロセッサが多すぎるなど)。 :)

22
Frank Heikens

ほぼすべての愚かなデータベースは、今日10億行を簡単に処理できます。 32ビットシステムでも5億は実行可能です(64ビットは本当に役立ちますが)。

主な問題は次のとおりです。

  • 十分なRAMが必要です。どれだけで十分かは、クエリによって異なります。
  • 十分なディスクサブシステムが必要です。これは、大規模な選択を行いたい場合、ほとんどすべてを意味する単一のプラッターは完全に問題外であることを意味します。 IO負荷を処理するには、多くのスピンドル(またはSSD)が必要です。

PostgresとMysqlはどちらも5億行を簡単に処理できます。適切なハードウェア上。

9
TomTom

確認したいのは、データベースソフトウェアが課すtable size limitです。たとえば、この記事の執筆時点では、 MySQL InnoDBの制限は64 TB per table であるのに対し、 PostgreSQLの制限は32 TB per table ;どちらもテーブルあたりの行数を制限しません。正しく構成されていれば、これらのデータベースシステムは数百または数千億行(各行が十分に小さい場合)の処理に問題はありません単独で5億行。

非常に大量のデータを最高のパフォーマンスで処理するには、十分なディスク容量と適切なディスクパフォ​​ーマンス(適切なRAIDのディスクで実現可能)、および高速プロセッサ(理想的にはサーバーグレード)と組み合わせた大量のメモリが必要です。 Intel XeonまたはAMD Opteronプロセッサ)。言うまでもなく、データベースシステムが最適なパフォーマンスのために構成されていること、およびテーブルが適切にインデックス付けされていることも確認する必要があります。

8
bwDraco

次の記事では、Microsoft SQLの16billion行テーブルのインポートと使用について説明します。 http://sqlmag.com/t-sql/adventures-big-data-how-import-16-billion-rows-single-table

記事から:

私の経験から得たいくつかのヒントを以下に示します。

定義されたクラスター化インデックスを持つテーブルにあるデータが多いほど、ソートされていないレコードをインポートするのが遅くなります。ある時点で、実用的になるには遅すぎます。テーブルをできるだけ小さいファイルにエクスポートする場合は、ネイティブ形式にします。これは、文字データよりもバイナリフィールドでよりコンパクトに表現されるため、主に数値列を含むテーブルに最適です。すべてのデータが英数字の場合、ネイティブ形式でエクスポートしてもそれほど利益はありません。数値フィールドにヌルを許可しないと、データがさらに圧縮されます。フィールドをヌル可能にすると、フィールドのバイナリ表現には、続くデータのバイト数を示す1バイトのプレフィックスが含まれます。 BCPカウンター変数は4バイト整数であるため、2,147,483,647レコードを超えるBCPを使用できません。 MSDNやインターネットでこれに関する参照を見つけることができませんでした。テーブルが2,147,483,647を超えるレコードで構成されている場合は、チャンクでエクスポートするか、独自のエクスポートルーチンを作成する必要があります。事前設定されたテーブルでクラスター化インデックスを定義するには、多くのディスク容量が必要です。私のテストでは、ログは完了前に元のテーブルサイズの10倍に爆発しました。 BULK INSERTステートメントを使用して多数のレコードをインポートする場合、BATCHSIZEパラメーターを含めて、一度にコミットするレコード数を指定します。このパラメーターを含めない場合、ファイル全体が単一のトランザクションとしてインポートされるため、大量のログスペースが必要になります。クラスタ化インデックスを使用してテーブルにデータを取得する最速の方法は、最初にデータを事前ソートすることです。その後、ORDERパラメーターを指定したBULK INSERTステートメントを使用してインポートできます。

SQL Server上に数十ペタバイト(数千テラバイト)と数兆行を収容するマルチペタバイトのNasdaq OMXデータベースと比較しても、それはわずかです。

5
Charles Burns

Cassandraをチェックアウトしましたか? http://cassandra.Apache.org/

2
adamzwakk

どのシステムを使用するのが最適かについてはあまり情報がありませんが、おそらくこのヒントは、あなたが探している速度の一部を得るのに役立つかもしれません。

長いvarchar文字列、特にインデックスで許可されているよりも長い文字列の完全一致を行う場合は、事前に計算されたハッシュのようなものを実行できます。

CREATE TABLE BigStrings (
   BigStringID int identity(1,1) NOT NULL PRIMARY KEY CLUSTERED,
   Value varchar(6000) NOT NULL,
   Chk AS (CHECKSUM(Value))
);
CREATE NONCLUSTERED INDEX IX_BigStrings_Chk ON BigStrings(Chk);

--Load 500 million rows in BigStrings

DECLARE @S varchar(6000);
SET @S = '6000-character-long string here';

-- nasty, slow table scan:
SELECT * FROM BigStrings WHERE Value = @S

-- super fast nonclustered seek followed by very fast clustered index range seek:
SELECT * FROM BigStrings WHERE Value = @S AND Chk = CHECKSUM(@S)

完全一致を実行していない場合、これは役に立ちませんが、その場合は、フルテキストインデックス処理を検討します。これにより、5億行のテーブルでのルックアップの速度が実際に変わります。

1
ErikE
選択クエリに対して十分なパフォーマンスを達成するために、インデックスを作成する必要があります(mysqlのような年齢を必要としません)。

インデックスを「作成」することの意味がわかりません。通常、これは1回限りです。さて、通常のように大量のデータを読み込む場合、インデックスを削除し、データを読み込んでからインデックスを追加し直すため、データの読み込みは非常に高速です。その後、データベースに変更を加えると、インデックスが更新されますが、クエリを実行するたびにインデックスを作成する必要はありません。

ただし、データベースにはクエリ最適化エンジンがあり、クエリを分析して、データを取得するための最適なプランを決定し、テーブルを結合する方法(シナリオに関係ない)と使用可能なインデックスを確認します。他の人がすでに指摘しているように、全テーブルスキャンを回避したいので、パフォーマンスチューニングとクエリプランのレビューが重要です。

チェックサムに関する上記のポイントは興味深いように見えますが、それは同じテーブルのattr1のインデックスである可能性さえあります。

1
michaelok

すでに述べたように、今日のすべてのDBはこの状況に対処できます。集中したいのは、ディスクI/Oサブシステムです。 RAID 0またはRAID 0 + 1の状況を設定して、できるだけ多くのスピンドルを問題に投げる必要があります。また、パフォーマンスのためにLog/Temp/Data論理ドライブを分割します。

たとえば、12台のドライブがあるとします-RAIDコントローラーで、それぞれ4ドライブのRAID 0パーティションを3つ作成します。 Windowsでは、各グループを論理ドライブ(G、H、I)としてフォーマットします。SQLServerを構成するときに(たとえば、tempdbをGに、ログファイルをHに、データファイルをIに割り当てます。

1
bigtang