3

整数の範囲を格納する大きなテーブルがあるとします。私は2つのフィールドでこれを行うことができます:

start|end
  10 |210     (represents 10 to 210)
  5  |55      (represents 5 to 55)

end(列ごとにすばやく選択)、または:

start|length
  10 | 200     (represents 10 to 210)
  5  | 50      (represents 5 to 55)

(列ごとにすばやく選択できlengthます)。

場合によっては で選択する必要がありend、場合によっては で選択する必要lengthがあり、両方のクエリを高速にする必要がある場合はどうすればよいでしょうか? 両方を保存できます:

start|length|end
  10 | 200  |210
  5  | 50   |55

しかし、これは正規化されておらず、誰もが両方のフィールドを更新することを覚えておく必要があり、設計が悪いだけです。

start + lengthorで選択できることはわかっていますend - startが、非常に大きなテーブルの場合、これは非常に遅くありませんか?

冗長なデータを保存せずに、計算された値ですばやくクエリを実行するにはどうすればよいですか? または、余分な列を保存するだけでよいでしょうか?

4

3 に答える 3

2

使用しているデータベースの種類によっては、トリガーを使用して派生フィールドを計算したい場合があります。そうすれば、同期がずれることはありません。

これは、開始または終了が変更されるたびに、フィールド (長さ) が再計算される可能性があることを意味します。

于 2012-10-08T02:11:01.433 に答える
1

長さを保存しますが、計算が挿入および更新 sproc で行われたことを確認して、誰もがあなたの sproc を使用している限り、オーバーヘッドが発生しないようにします。

于 2012-10-08T02:11:26.960 に答える
1

残念ながら、どちらのターゲット データベースも計算列をサポートしていません。私は次のことをします:

  1. まず、本当にパフォーマンスの問題があるかどうかを判断します。WHERE end - start = ?のパフォーマンスが よりも遅いのは事実ですWHERE length = ?が、アプリケーションで「非常に大きなテーブル」とは何か、また必要なパフォーマンスは何かを定義していません。存在しないかもしれない問題を最適化する必要はありません。
  2. 検索の待ち時間をサポートできるかどうかを判断します。その場合は、計算列をテーブルに追加できますが、値を入力するために 5 分ごと、1 時間ごとなど、別のタスクを実行する必要があります。
  3. PostgreSQL ではマテリアライズド ビューを検討できますが、これはエンジン レベルでサポートされていると思います。(以下の Catcall のコメントを参照してください)。
  4. 最後に、他のすべてが失敗した場合は、トリガーを使用して計算列を維持することを検討してください。
于 2012-10-08T11:32:52.567 に答える