JSON 上的 PostgreSQL 索引

2024-01-12

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

例如,我有一个“农场”表,其中包含 json 列“动物”。

Animals 列具有通用格式的 json 对象:

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

我已经尝试了一些索引(分别):

  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) 索引有效,但我无法让任何索引适用于不等式。

这样的索引可能吗?

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


您的其他两个索引将不起作用,因为->>操作员 https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSON-OP-TABLE回报text,而你显然有jsonb考虑到杜松子酒操作员类别。请注意,您只提到json,但你实际上需要jsonb https://www.postgresql.org/docs/current/datatype-json.html用于高级索引功能。

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

假设:

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

我建议使用功能性 btree 索引,就像您已经拥有的那样,但将值转换为integer。我认为您不希望将比较评估为text(其中“2”大于“1111”)。

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

强制转换速记需要额外的括号,以使索引表达式的语法明确。

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

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

如果您需要更通用的jsonb索引,考虑:

  • 在 Postgres jsonb 中查询数组中的结构的正确索引是什么? https://stackoverflow.com/questions/26499266/whats-the-proper-index-for-querying-structures-in-arrays-in-postgres-jsonb/27708358#27708358

For a 已知的、静态的、琐碎的动物的数量(就像你评论的那样),我建议部分索引,例如:

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;

Etc.

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JSON 上的 PostgreSQL 索引 的相关文章

随机推荐

  • Android 标记自定义信息窗口

    我正在使用谷歌地图V2 我需要展示ListView 风俗ListView带图像 自定义InfoWindow 我尝试过并且只在以下方面取得了成功View 问题是我无法得到listItemClick event googleMap setInf
  • 当函数属于必须解析的类时,如何向 IServiceCollection 注册委托或函数?

    我正在使用 Microsoft Extensions DependencyInjection 中的 IServiceCollection IServiceProvider 我想将委托注入到一个类中 public delegate Valid
  • Java 将表面分割成小方块

    我想知道是否有任何算法可以执行以下操作 给定一个特定的表面 它将其分成相同大小的更小的矩形 像这个示例图一样 灰色区域是表面 红色方块是分区本身 我在想是否有一种优化的方法来做到这一点 一个非常糟糕的方法是在所有像素中进行 for 循环 并
  • 将日期格式更改为 ddth mmm,yyyy

    我正在网络表单上打印一些日期 目前我的日期格式是dd mmm yyyy hh mm 如何将日期格式更改为ddth mmm yyyy for例子2016年5月17日 hh mm 这是我的代码 lastlogin DateTime Parse
  • /usr/bin/ld: 找不到 -lpthreads

    我正在 Fedora 22 上编译 NVIDIA Caffe 工具 但遇到问题需要查找lpthread图书馆 Determining if the pthread create exist failed with the following
  • 如何更改R图表中的默认字体大小

    我正在使用 R 包 cooccurr 无法弄清楚如何更改关联图形中的字体大小 par 方法似乎不起作用 这是包中给出的示例 data finches cooccur finches lt cooccur mat finches type s
  • 模块模式与匿名构造函数的实例

    于是就有了这个所谓的模块模式用于创建具有私有成员的单例 var foo function var foo private return foo function console log foo bar public 还有这个方法是我自己找到
  • 如何使用 click 来解析字符串中的参数?

    假设我有一个包含参数和选项的字符串列表 其中argparse 我可以使用以下方法解析这个列表parse args将函数转化为对象 如下 import argparse extra params sum 7 1 42 parser argpa
  • 如果中断 Git 推送会发生什么?

    我运行了以下命令 git push u origin master 推送 非常大 文件很多 所以上传需要时间 中途我发现我忘记添加几个文件 所以我做了 Ctrl C 在终端 中断 Git 然后做完之后git add 我又承诺了 然后又推了
  • DDD - 如何设计不同限界上下文之间的关联

    我已经设置了一个正在使用 ORM 填充的域项目 该域包含不同的聚合 每个聚合都有自己的根对象 我的问题是应该如何处理跨越聚合边界的属性 这些属性是否应该简单地忽略边界 以便有界上下文 A 中的域对象可以引用上下文 B 中的对象 或者 是否应
  • 如何检查一次 UserDefaults 是否为空

    我的应用程序计算日期和 NSDate 之间的天数 当我发布它时 用户只能保存一个日期 一个标题和一张背景图像 现在我有一个 UICollectionView 可以选择保存多个日期 并且它将通过将日期 标题和图像字符串附加到各自的数组来创建一
  • 分叉进程的执行顺序

    我知道还有另一个同名的线程 但这实际上是一个不同的问题 当一个进程多次分叉时 父进程是否先于子进程完成执行 反之亦然 同时 这是一个例子 假设我有一个 for 循环 将 1 个父进程分叉为 4 个子进程 在 for 循环结束时 我希望父进程
  • 使用 Json.net 反序列化具有接口值的复杂嵌套字典类型

    我在尝试使用 Json net 反序列化具有接口值的相当复杂的嵌套字典类型时遇到问题 代码位于此处 https dotnetfiddle net JSoAug https dotnetfiddle net JSoAug 有问题的类型是 pu
  • python 我可以向 os.listdir 提供用户名和密码吗?

    Python 3 4 Django 1 7 Windows Apache 2 4 12 我试图列出 Windows 共享驱动器上的所有文件 仅限某些用户 然后将几个文件写入共享驱动器 我正在使用 os listdir 来执行此操作 如果我只
  • 如何使用 Selenium webdriver 在 Capybara 中打开新窗口?

    我找到了一段代码 page driver browser switch to window 这显然是切换到已经打开的窗口 我们如何使用 page driver browser 对象打开一个新窗口 Thanks 我最终来到这里 即使是一个旧线
  • 没有匹配的函数调用“pthread_create”

    我正在使用 Xcode 和 C 制作一个简单的游戏 问题是下面的代码 include
  • 为什么在宏中使用明显无意义的 do-while 和 if-else 语句?

    在许多 C C 宏中 我看到宏的代码被包裹在看似毫无意义的内容中 do while环形 以下是示例 define FOO X do f X g X while 0 define FOO X if 1 f X g X else 我看不到什么d
  • 尽管身份密钥计数器在 TRY Catch 中且事务已回滚,但它仍会增加 1? SSMS 2008

    尽管身份计数器在 TRY Catch 中且事务已回滚 但它仍会增加 1 SSMS 2008 有什么方法可以阻止它 1 或回滚它 为了理解为什么会发生这种情况 让我们首先执行下面的示例代码 USE tempdb CREATE TABLE db
  • 将 Abaqus 宏转换为 Python 脚本

    我正在使用 Abaqus 6 13 运行 FEM 热模拟 我需要获得应用于该模型的总外部热通量 我的搜索表明 获得它的唯一方法是对整个模型的 RFLE 历史输出求和 并且效果很好 问题是我有大约 300 000 个元素模型 并且简单打开 R
  • JSON 上的 PostgreSQL 索引

    使用 Postgres9 4 我想在 json 列上创建一个索引 该索引将在搜索列中的特定键时使用 例如 我有一个 农场 表 其中包含 json 列 动物 Animals 列具有通用格式的 json 对象 cow 2 chicken 11