我有以下构造函数(作为测试):
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
但我相信正确的方法是使用@&gt;运营商。我有以下内容,但它给出了语法错误:
SELECT COUNT(id)
FROM (
SELECT id
FROM product
WHERE ext @> 'size>=41,mass<=20'
) T
我该怎么写呢?
答案 0 :(得分:6)
您的初始尝试是正确的,但您需要使用(部分)btree索引和位图索引扫描来依赖它:
create index on product(((ext->'size')::int)) where ((ext->'size') is not null);
相同的质量,如果规划师没有当场得到它添加两个where子句,即where ext->'size' is not null
和质量相同。
如果存在某种模式(很可能,因为大多数产品的尺寸也有质量),可能会创建一个多列索引,将两个 - 一个囊组合,另一个组合。
您编写的gin索引以及随附的查询(语法错误)基本上会执行相同的操作但无序;它会慢一些。
答案 1 :(得分: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。