0

mysql データベース内のテーブルには 2 つの列があります。最初の列にはフィンガープリントが含まれ、2 番目の列にはそのフィンガープリントを持つドキュメントのリストが含まれます。これは、検索エンジンによって作成された逆索引によく似ています。テーブル内のレコードのインスタンスを以下に示します。

34 "doc1, doc2, doc45"

フィンガープリントの数は非常に多い (数兆に及ぶ可能性がある)。データベースには基本的に次の操作があります: レコードの挿入/更新 & 指紋の一致によるレコードの取得。テーブル定義の Python スニペットは次のとおりです。

self.cursor.execute("CREATE TABLE IF NOT EXISTS `fingerprint` (fp BIGINT, documents TEXT)")

挿入/更新操作のスニペットは次のとおりです。

if self.cursor.execute("UPDATE `fingerprint` SET documents=CONCAT(documents,%s) WHERE fp=%s",(","+newDocId, thisFP))== 0L:
                self.cursor.execute("INSERT INTO `fingerprint` VALUES (%s, %s)", (thisFP,newDocId))         

これまでに観察した唯一のボトルネックは、mysql でのクエリ時間です。私のアプリケーション全体は Web ベースです。したがって、時間は重要な要素です。カサンドラの使用も考えましたが、知識があまりありません。この問題に取り組むためのより良い方法を教えてください。

4

3 に答える 3

2

ハイエンド データベースを取得します。オラクルにはいくつかのオファーがあります。SQL Server も。

数兆のエントリは、通常のデータベースの範囲をはるかに超えています。これは、特にまともなパフォーマンスが必要な場合に、非常にハイエンドで非常に特別なものです。また、そのためのハードウェアを入手してください。これは、適切なミッドレンジ サーバー、キャッシュ用の 128 GB 以上のメモリ、および適切な SAN または SAS を介した十分な DAS セットアップのいずれかを意味します。

覚えておいてください、TRILLIONS は次のことを意味します。

  • すべてのバイトに 1000 GB が使用されます。

フィンガープリントが int64 として保存されている場合、このデータだけでも 8000 GB のディスク容量が必要です。

それとも、2 TB のディスクが 2 枚入った小さな安価なサーバーから実行してみますか? 幸運を。

于 2010-12-30T05:39:59.273 に答える
1

そのデータ構造は SQL にはあまり適していません。SQL の「正しい」設計は、フィンガープリント/ドキュメントのペアごとに行を持つことですが、あまりにも多くのスペースを占有するインデックスを追加しない限り、クエリは信じられないほど遅くなります。 . あなたがやろうとしていることに対して、SQLは、必要な複数の値の列をサポートしていないのに、必要のない関数をサポートするために多くのオーバーヘッドを追加します。

Redis クラスターが適している可能性があります。アトミック セット操作は、実行している作業に最適であり、適切な仮想メモリのセットアップと、フィンガープリントをノード間で分散するための一貫したハッシュにより、データ ボリュームを処理できるはずです。コマンドは次のようになります

SADD fingerprint, docid

レコードを追加または更新する

SMEMBERS fingerprint

そのフィンガープリントですべてのドキュメント ID を取得します。

SADD は O(1) です。SMEMBERS は O(n) ですが、n はセット内のドキュメントの数であり、システム内のドキュメント/フィンガープリントの数ではないため、この場合も事実上 O(1) になります。

現在使用している SQL 挿入は O(n) であり、n はレコードの総数が非常に大きいため、レコードは、両方の get に対して一定時間であるハッシュ テーブルではなく、挿入時に並べ替える必要がある順序付きリストとして格納されるためです。設定します。

于 2010-12-31T01:38:06.053 に答える
0

Greenplum データ ウェアハウス、FOC、postgres ドリブン、頑張ってください ...

于 2010-12-30T06:14:55.440 に答える