1

カスタム データ セットを格納する Rails アプリケーションを作成中です。より具体的には、リーダーボードのアーカイブを保存しています。Leaderboard にはそれぞれ、カスタム フィールドを持つことができる LeaderboardEntries のセットがあります (つまり、すべての Leaderboard が同じフォーマットを持つわけではありません)。

簡単な例:

Leaderboard 1 (Fields)
-------------
7_day_exponential_moving_average
total_count

Leaderboard 2 (Fields)
-------------
10_day_exponential_moving_average
total_count

現在、リーダーボードのすべてのエントリを「データ」と呼ばれるリーダーボードのフィールドにシリアル化しています。その結果、30,000 以上のオブジェクトに対して計算を実行し、結果を 1 つのフィールドに格納しています。

非同期で計算を実行するときにこれに欠陥があることがわかり始めています (すべての計算が完了するのを待ち、計算が完了したかどうかを監視し、すべてのデータを保存する必要があります)、LeaderboardEntry という別のモデルを作成しているように見えますより理にかなっています。私が疑問に思っているのは、30,000 の個別のオブジェクトを格納してクエリを実行することと、30,000 のエントリすべてを 1 つのフィールドに格納することのパフォーマンス ヒットです。

私は、1 回の応答で 1 回の要求を実行すると、はるかに優れたパフォーマンスが得られると考えました。(すなわち

SELECT serialized_data FROM leaderboards WHERE leaderboard_id=123  <-- 1 row with a very large field

SELECT * FROM leaderboard_entries WHERE leaderboard_id=123 <-- 30,000 rows with small sets of data

シリアル化されたフィールドに格納するという私の仮定は正しいですか? それとも、エントリを個別に保存することはそれほど大したことではありませんか? ここで私が考えたもう 1 つの考え: MongoDB のような nosql ソリューションを使用する方が効率的であり、leaderboard_entry フィールドで並べ替えて、結果を少量 (一度に 50 個の結果) に制限することができます。

最終的には、1 日あたり 100 万以上のリーダーボード エントリ (20 以上のリーダーボードの場合) を生成することになり、それらを格納する最も効率的な方法を見つけようとしています。

ありがとう!

4

1 に答える 1

4

大きなシリアル化されたフィールドは、小さなエントリの集まりよりも保存と取得が確実に効率的になります (Postgres はすべてを CLOB として保存します)。とはいえ、これはほぼ確実に時期尚早の最適化です。正規化されたデータの利点は重要です。 を使用して 30k 行のクエリをセグメント単位でステップ オーバーできるselect where field > xxx and field < yyyため、アクセス時間が非常に速くなります。Postgres は、多数の小さなオブジェクトに対して非常に効率的に操作を実行できます。データが半構造化されているだけの場合は、postgres がクエリで検査できる「hstore」および JSON データ型を確認してください。

これは、データベースの切り替えを検討するほど大きな問題ではないようです。MongoDB は、ここですぐに利点を得ることができません。ほとんどの問題は、データ アクセス用のクエリをどのように設計するかにあります。たとえば、適切なインデックスを使用して部分的なデータセットを選択すると、大きな制限のない を実行するよりも常に高速になりますselect *

実行すると予想されるクエリの種類について「explain plan」を確認し、それに応じて調整してください。さまざまな種類のクエリのコストに関心がある場合は、一連のテスト データをテスト データベースにロードし、Postgres が作成するクエリ プランを調べると便利なことがよくあります。さまざまなクエリ プランのコストの相対的な数値は、稼働時に問題点がどこにあるのかを示す非常に効果的なガイドです。

于 2013-02-01T19:55:04.543 に答える