Tar*_*len 5 postgresql indexing
我在PG 9.5上,并且有一张桌子 Visitors(id, data::json)
例:
Visitor(id: 1, data: {name: 'Jack', age: 33, is_user: true })
Run Code Online (Sandbox Code Playgroud)
我想执行类似的查询
用户指定的数据列中的键是动态的。
在这种情况下,哪个索引最有意义?
您可以在jsonb列上使用GIN索引,从而为JSON值内的键和值提供通用的动态索引。
CREATE TABLE visitors (
id integer,
data jsonb
);
CREATE INDEX idx_visitors_data ON cards USING GIN (data);
SELECT * FROM visitors
WHERE data -> 'is_user' AND NOT data ? 'name';
Run Code Online (Sandbox Code Playgroud)
不幸的是,GIN索引不支持数字范围比较。因此,尽管您仍然可以对年龄超过25岁的杰克访客进行查询:
SELECT * FROM visitors
WHERE data @> '{"name": "Jack"}' AND ((data ->> 'age')::integer) > 25;
Run Code Online (Sandbox Code Playgroud)
这将仅使用索引查找名称“ Jack”,并可能查找具有“ age”键的行,但是将对匹配的行进行扫描,以进行年龄超过25岁的实际测试。
请注意,如果您确实需要范围比较,但如果您希望它们出现的次数足够使之有价值,那么仍然可以在JSON值内的特定路径上添加非GIN索引。例如,您可以在data -> 'age'
支持范围比较的索引上添加:
CREATE INDEX idx_visitors_data_age ON visitors ( ((data ->> 'age')::integer) );
Run Code Online (Sandbox Code Playgroud)
(请注意多余的括号;如果没有它们,您将得到一个错误)。
有关更多信息,请参见这篇出色的博客文章。
归档时间: |
|
查看次数: |
2564 次 |
最近记录: |