3

私は次のコンストラクターを持っています(テストとして):

CREATE TABLE product (id BIGSERIAL PRIMARY KEY, ext hstore);
CREATE INDEX ix_product_ext ON product USING GIN(ext);

INSERT
INTO    product (id, ext)
SELECT  id, ('size=>' || CEILING(10 + RANDOM() * 90) || ',mass=>' || CEILING(10 + RANDOM() * 90))::hstore
FROM    generate_series(1, 100000) id;

私は次のクエリを持っていますが、これは問題なく機能します:

SELECT  COUNT(id)
FROM    (
    SELECT  id
    FROM    product
    WHERE  (ext->'size')::INT >= 41
    AND    (ext->'mass')::INT <= 20
) T

しかし、これを行う正しい方法は@>演算子を使用することだと思います。次のものがありますが、構文エラーが発生します。

SELECT  COUNT(id)
FROM    (
    SELECT  id
    FROM    product
    WHERE  ext @> 'size>=41,mass<=20'
) T

これはどのように書くべきですか?

4

2 に答える 2

6

最初の試みは正しいですが、それに依存するには(部分的な)btreeインデックスとビットマップインデックススキャンを使用する必要があります。

create index on product(((ext->'size')::int)) where ((ext->'size') is not null);

質量についても同じです。プランナーがその場でそれを取得できない場合は、2つのwhere句を追加します。つまりwhere ext->'size' is not null、質量についても同じです。

ある種のパターンがある場合(おそらく、サイズのあるほとんどの製品にも質量があるため)、2つを組み合わせたマルチカラムインデックスを作成する可能性があります。1つはsac、もう1つはdescです。

あなたが書いたginインデックスとそれに付随するクエリ(構文エラーあり)は基本的に同じことをしますが、順序付けされていません。遅くなります。

于 2011-06-24T22:46:50.790 に答える
3

あなた(最後のクエリ)のhstoreドキュメントを読んsize>=41でも、「サイズが41以上の場合」という意味ではありません。

text => text    make single-pair hstore

それに続いて、そのような操作がないため、書くことはできませんmass<=20@>演算子の使用:

hstore @> hstore    does left operand contain right?

あなたは書ける:

SELECT count(id)
FROM product
WHERE ext @> 'size=>41,mass=>20';

ただし、サイズが 41 に等しく、質量が 20 に等しいこれらの製品のみが必要です。

于 2011-06-24T22:09:27.710 に答える