使用Postgres 9.4,我想在json列上创建一个索引,在搜索列中的特定键时将使用该索引.

例如,我有一个带有json列"animals"的"farm"表.

"动物"列包含通用格式的json对象:

'{"cow": 2, "chicken": 11, "horse": 3}'

我try 了许多索引(分别):

  1. create INDEX animal_index ON farm ((animal ->> 'cow'));
  2. create INDEX animal_index ON farm using gin ((animal ->> 'cow'));
  3. create INDEX animal_index ON farm using gist ((animal ->> 'cow'));

我想运行如下查询:

SELECT * FROM farm WHERE (animal ->> 'cow') > 3;

并让该查询使用索引.

当我运行此查询时:

SELECT * FROM farm WHERE (animal ->> 'cow') is null;

然后(1)指数起作用,但我不能让任何指数对不等式起作用.

Is such an index possible?

farm表只包含约5000个农场,但其中一些包含100个动物,对于我的用例来说,查询时间太长.像这样的索引是我能想到的加快查询速度的唯一方法,但也许还有另一种 Select .

推荐答案

其他两个索引无法工作,因为->> operator返回102,而您显然考虑了jsonb个gin运算符类.请注意,您只提到了json,但实际上需要jsonb才能获得高级索引功能.

为了制定出最佳的索引策略,您必须更仔细地定义要覆盖哪些查询.你只对牛感兴趣吗?还是所有动物/所有标签?哪些运营商是可能的?JSON文档是否也包含非动物密钥?这些怎么办?您想在索引中包含那些在JSON文档中根本不显示cows(或其他内容)的行吗?

100

  • 我们只对筑巢第一阶段的奶牛感兴趣.
  • 该值始终为有效的integer.
  • 我们对没有奶牛的行列不感兴趣.

我建议使用一个功能性的btree索引,就像你已经拥有的一样,但将其值设为integer.我认为您不希望比较结果被判断为text(其中"2"大于"1111").

CREATE INDEX animal_index ON farm (((animal ->> 'cow')::int));  -- !

cast速记需要额外的一组括号,以使索引表达式的语法明确无误.

在查询中使用相同的表达式,让Postgres意识到索引是适用的:

SELECT * FROM farm WHERE (animal ->> 'cow')::int > 3;

如果需要更通用的jsonb指数,请考虑:

对于known, static, trivial多种动物(如您所 comments 的),我建议使用以下部分索引:

CREATE INDEX animal_index ON farm (((animal ->> 'cow')::int))
WHERE (animal ->> 'cow') IS NOT NULL;

CREATE INDEX animal_index ON farm (((animal ->> 'chicken')::int))
WHERE (animal ->> 'chicken') IS NOT NULL;

您可能需要将索引条件添加到查询中:

SELECT * FROM farm
WHERE (animal ->> 'cow')::int > 3
AND   (animal ->> 'cow') IS NOT NULL; 

可能看似多余,但可能是必要的.用ANALYZE来测试!

Sql相关问答推荐

Oracle SQL中的累计总数

在SQL Server中使用LEFT连接包含特定记录

在数据分区内执行确定

无法找到正确的SQL查询需求

如何在一个范围内进行分组.""范围值在范围表中定义

数据库索引:如何使用名称和类别对项目进行最佳索引?

按每天的最大值分组

连接三个表的正确方式是什么?在这三个表中,可以显示在一个表上的行将在其他表中显示结果

使用DatePart函数对日期时间值进行分组

无法将发票与产品价格相关联

使用SQL数据库中的现有列派生或修改几个列

如何将不同层次的产品组和规格组合到最深一层?

此过程如何在不引用传递的参数值的情况下执行工作?

如何使用jsonn_populate_record()插入到包含IDENTITY列的表中

group-by-clause具有特定列,而不是oracle的toad中的all

达到特定值时,从0开始累加求和

SQL 按 id 运行总计并受条件限制(在窗口上)

如何筛选 GROUP BY 结果? HAVING 没有产生预期的结果

CURRENT_ROW 窗口框架上的 SQL 滞后

每组跨行曲折?