PostgreSQL - запрос к индексу GIN значения HSTORE - PullRequest
3 голосов
/ 25 июня 2011

У меня есть следующий конструктор (в качестве теста):

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

Как мне написать это?

Ответы [ 2 ]

6 голосов
/ 25 июня 2011

Ваша первоначальная попытка верна, но вам нужно использовать (частичные) индексы btree и растровые индексы, чтобы полагаться на них:

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

То же самое для массы, и если планировщик не получает это на месте, добавьте два предложения where, то есть where ext->'size' is not null и то же самое для массы.

Если есть какой-то шаблон (который, вероятно, так как большинство продуктов с размером также имеют массу), потенциально создайте многоколонный индекс, объединяющий два - один мешочек, другой деск.

Индекс джина, как вы его написали, вместе с сопровождающим запросом (с синтаксической ошибкой) в основном будут делать то же самое, но неупорядоченно; это будет медленнее.

3 голосов
/ 25 июня 2011

Чтение 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.

...