2

私のプログラミング環境はRails2.3とPostgreSQL8(Herokuの共有データベース)です。アプリの構築を開始する前に、インターネットでこの http://devcenter.heroku.com/articles/postgresql-indexes#multicolumn_indexes およびその他の関連リソースを読みました。一般的な方法で:

私のテーブルには2つの列AとBがあり、両方ともインデックスが付けられています。(行は(A、B)ペアの点で一意です)しかし、アプリをビルドした後、myTable.find_by_A_and_B(a、b)とmyTable.find_by_A(a)の2種類の呼び出しでのみテーブルをクエリすることがわかりました。 )。

テーブルには10000以上のエントリがあると予想され、個別のAと個別のBの比率は約3:1です。Aの一意の値ごとに、Bの値が異なる1000以上の行があると予想されます。また、Bの一意の値ごとに、Aの値が異なる行は300行以下になります。

私の質問は、現在のデータベース設定(2つの別々のインデックスを使用)がmyTable.find_by_A_and_B(a、b)呼び出しに関して「効率的」として分類できるかどうかです(PostgreSQLの内部動作についてはわかりません)。また、2つのインデックスを(A、B)の1つのマルチ列インデックスに置き換えるだけで、大幅な速度向上が実現するかどうか。

ありがとうございました。

PSコメントに応えて、もう少し情報があります。このページによると、http://devcenter.heroku.com/articles/databasePostgreSQL8.3 を実行しています。

そして、以下はmyTableの移行スキーマです。

create_table :myTable do |t|
    t.string :b
    t.integer:a
    t.boolean :c, :default => false
end

add_index :mytable, :b 
add_index :mytable, :a
4

1 に答える 1

1

PostgreSQL の最近のバージョンでは、複数列インデックスを効率的に使用して、列の 1 つだけをフィルタリングできます。これは最初の列で最もうまく機能しますが、他の列でもかなりうまく機能します。

また、10.000 行は PostgreSQL にとって簡単なことです。数百万行のテーブルは珍しくありません。

整数(int4) 列のbtree インデックス (デフォルト) について話していると仮定すると...
...答えは: で1 つの複数列インデックスを(a,b)使用するだけです。

ディスク上のページ レイアウト(テーブルとインデックスと同様) により、インデックス行ごとにかなりのオーバーヘッドが発生します。また、データ アライメントの制限により、8 バイトのマシン (ほとんどの 64 ビット OS) では、1 つのインデックスが1つのインデックス(a,b)とまったく同じ量のディスク領域を使用します。 したがって、特に書き込みが多い場合、またはディスク容量や RAM が限られている場合は、. 頻繁に書き込まれるテーブルのインデックスを維持することにも、かなりのコストがかかります。(a)MAXALIGN
(a,b)

質問の更新に応じて編集します。

  • aあるintegerため、私の答えはほとんど有効です。上のインデックスは、(a,b)必要なもののすべてまたはほとんどになります。

  • b明らかにクエリを持っていないので、別のインデックスを取り除きbます。

  • bそのままでは、(a,b) の複数列インデックスは、上記textのようにデータ配置から利益を得ることができませんが、それでもなおです。の中間の長さが大きいほど、bだけの追加のインデックスから利益を得る可能性が高くなりますa。短いbと、おそらく支払われません。myTable.find_by_A(a)それ以外の場合は、少しだけ高速化することを期待しています。

  • aこれは、との 2 つの個別のインデックスよりもおそらく高速ですbが、Postgres はbitmap index scan. これは v.8.3 から改善されました。

  • btree インデックスは、「=」を使用したヘルプ クエリのみであることに注意してください(ロケールtextで実行する場合はさらに多くなります)。演算子クラスCに関するマニュアルを読んでください。

EXPLAIN ANALYZEでいくつかのテストを実行してください。これは非常にシンプルで有益であり、10.000 行のインデックス作成はほんの数秒で完了します。各クエリを数回繰り返してキャッシュにデータを入力し、比較可能な結果を​​取得します。

于 2011-09-25T20:38:48.377 に答える