4

text[](配列)列が定義されたPostgreSQLデータベーステーブルがあります。これらの列を使用して、データベース内の特定のレコードを次のように検索しています。

select obj from business
where ((('street' = ANY (address_line_1)
    and 'a_city' = ANY (city)
    and 'a_state' = ANY (state))
or    ('street' = ANY (address_line_1)
    and '1234' = ANY (zip_code)))
and ('a_business_name' = ANY (business_name)
    or 'a_website' = ANY (website_url)
    or array['123'] && phone_numbers))

私が抱えている問題は、約100万件のレコードがあると、クエリが非常に遅くなることです。私の質問は単純ですが、配列列にはさまざまな種類のインデックスがありますか?この場合に作成するのに最適なインデックスのタイプを知っている人はいますか?(さまざまなタイプがあると仮定します)。

念のため、これがexplain analyze応答です。

"Seq Scan on business  (cost=0.00..207254.51 rows=1 width=32) (actual time=18850.462..18850.462 rows=0 loops=1)"
"  Filter: (('a'::text = ANY (address_line_1)) AND (('a'::text = ANY (business_name)) OR ('a'::text = ANY (website_url)) OR ('{123}'::text[] && phone_numbers)) AND ((('a'::text = ANY (city)) AND ('a'::text = ANY (state))) OR ('1234'::text = ANY (zip_code))))"
"  Rows Removed by Filter: 900506"
"Total runtime: 18850.523 ms"

前もって感謝します!

4

1 に答える 1

3

GINインデックスを使用して、アレイのパフォーマンスを効果的に向上させることができます。配列演算子
と組み合わせて使用​​します。

例えば:

CREATE INDEX business_address_line_1_idx ON business USING GIN (address_line_1);

条件に関係するすべての配列列に対してこれを行います。

代わりに、スキーマを正規化することを検討する価値があるかもしれません。たぶん、複数のエントリを別々の(1:nまたはn:m)テーブルに分割するとより効果的です。最初はもっと仕事が多いように見えても、長期的にはそうなることがよくあります。

于 2013-01-28T21:25:54.823 に答える