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);

质量相同,如果计划者没有当场得到它,则添加两个 where 子句,即where ext->'size' is not null质量相同。

如果存在某种模式(很可能,因为大多数具有大小的产品也有质量),可能会创建一个结合两者的多列索引 - 一个 sac,另一个 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 回答