web-dev-qa-db-ja.com

動的フォームビルダーデータベース最適化Postgresql

こんにちは、動的にフォームを作成するプロジェクトがあります。次のようなモデルを使用します。

forms
-----
  id (PK)
  name
  (other fields)

form_fields
-------------
  id (PK)
  form_id (FK to forms.id)
  label (nome to the field)

form_submits (form inserted by someone user)
-------------
  id (PK)
  form_id (FK to forms.id)
  user_id (FK to users.id)

form_submits_fiels 
-------------
  id (PK)
  form_fields_id (FK to form_fields.id)
  form_submit_id (FK to form_submit.id)
  data 

form_elementテーブルには1.500.000を超える行があります。数は増え続け、フォームのすべてのレコードを返す関数には20秒以上かかります。問題は、モデルまたはクエリを最適化することで、より短い時間で実行できることです。

私はいくつかのアイデアを持っていますが、問題を解決しないものがあります:

  • Paginate:クエリにページ番号を付けることができた場合、パフォーマンスは非常に向上しますが、データが整然としていないため不可能です。
  • MongoDB:リレーショナルモデルを使用しない場合、パフォーマンスは向上するかもしれませんが、マッハがMongoを使用するとパフォーマンスが向上する可能性があり、非常に高価なソリューションです
3
oriaj

もっと評判がよければ、インデックスについて説明するようにお願いするコメントを追加します。現状では、インデックスについて言及しなかったため、インデックスがないと仮定します。

まず、クエリでEXPLAINを使用して、プランナが行う決定を分析することを検討してください。 1.5mの行は、ハードウェアとインデックスのあらゆる種類の合理的な組み合わせで20秒かかることはありません。 EXPLAIN修飾子のドキュメント を参照してください。実際にクエリを実行して得られたコストの内訳とタイミング情報、さらに重要なことには各ステージに入る個々のプロセスを確認するには、_(ANALYZE on)_を含める必要があります。

第2に、このようなスキーマは、インデックスだけでなく、マルチカラムインデックスの限られた使用からも利益を得ます。 ( _CREATE INDEX_のドキュメント を参照してください。)以下にインデックスを作成することを検討してください。

  • form_fields.formid、form_fields.id
  • form_submits.formid、form_submits.id

その他。それはあなたのコードが何をしているかに大きく依存します。データベースを別のサーバーに複製し、インデックスの異なる構成を作成して、それに対してコードを実行します。 (EXPLAIN (ANALYZE on)再びここに!)複数列のインデックスは、プランナがインデックスの1回のパスで複数のフィルタリング/並べ替え基準をチェックするのに役立つため、優れています。

3番目に、最後のポイントに対処するために、ページ付けや非リレーショナルモデルへの移行が役立つかどうかはわかりません。外部キーを使用しているという事実は、実際には強力なリレーショナルデータセットを指しています。もちろん、無料でMongoDBを試して、パフォーマンスがどのようになるかを確認することもできます。

1