【发布时间】:2020-12-14 00:30:28
【问题描述】:
我测试了以下脚本:
CREATE TABLE test (
id serial NOT NULL PRIMARY KEY,
obj jsonb NOT NULL
);
INSERT INTO test (obj)
VALUES('{ "a": "foo", "b": ["cat" , "dog", "horse"]}'),
('{ "a": "bar", "b": ["cat" , "dog", "mouse"]}'),
('{ "a": "baz", "b": ["dog" , "pig", "cow"]}');
create index on test (((obj #>> '{a}')), ((obj #>> '{b}')) );
EXPLAIN ANALYZE SELECT *
FROM test
WHERE (obj #>> '{a}') = 'bar' AND (obj #> '{b}') ? 'mouse';
实际上我插入了几千行只是为了确保 pg 尽可能使用索引。
我希望查询将使用索引的两个路径。它不是。即使我将索引定义替换为:
create index on test (((obj #>> '{a}')), ((obj #> '{b}')) );
它将仅使用定义的 {a} 部分,然后对我的查询的 {b} 部分使用过滤。
我知道至少有一个 (xml) 数据库,在多次出现的元素上使用 btree 索引定义只会在每次出现的索引中放置一个键(结合其余索引值)。当然,这会产生一个大索引,但查询又好又快。
当然,对于 pg/json,我可以使用 GIN 索引,但总的来说我更喜欢多个目标索引。
所以,我的问题是双重的:
- 当我根据上述语句创建索引时,pg/json 究竟意味着什么?因为 pg 愉快地接受了索引的创建,所以没有错误。
- 是否可以使用 btree 索引对数组进行索引并使其支持使用包含数组的谓词进行查询?
【问题讨论】:
-
查询
obj #>> '{a}') = 'bar'返回多少行。 -
GIN 索引正是为这个用例创建的。
-
如果我尝试 "= 'bar'" 查询,则返回 0 行。该谓词实际上是您将在 xquery/xml 中用于此类搜索的内容,并且在我通过 b-tree 索引引用的 XML 数据库中得到支持。
标签: json postgresql indexing