json 字段检查和字段范围查询的最佳索引是什么

What's the best index for a json fields checking and fields range queries

假设我们有以下 table:

我有以下对象:

struct Tick = { country string region string type string spec map string -> int # {v1: n1, v2:n2} t timestamp }

我想将此对象存储在 Posgresql 9.4 中。将有数百万个。 90% 的查询将涉及:

以上所有查询组合都是均匀分布的。 然后大约 5% 将额外涉及检查规范属性:存在或范围。

在 Postgresql 9.4 中编码此类对象的最佳方法是什么?应该创建哪个索引?

一些想法:

  1. 将所有字段编码为单个字符串并进行正则表达式查询。例如:encoded = "type;country;v1:n1;v2:n2"。那么,是否可以创建一个复合索引 (t, encoded),它允许对 t 进行范围查询,对 encoded 进行正则表达式查询?在这种方法中,我们取消了索引中的规范范围检查,
  2. 编码 jsonb 中的所有内容。那么,是否可以对某些jsonb属性进行索引范围查询?

[编辑]
广告。 1. 可以将这些值放在 table (tab = {type, country, v1+n1, ...}) 中并创建 gin 索引:gin (t timestamp_ops, tab _text_ops) 使用 btree_gini 扩展名,而不是将这些值编码为单个字符串。

保持简单。使用常规 table 和复合索引。

我会看类似的东西:

CREATE OR REPLACE TABLE blah (
  country text,
  region text,
  type text,
  spec json,
  t timestamp not null
);

那里没有明显的候选键,因此您可能还需要一个合成主键。

然后在数据上有一个或多个复合索引,比如

CREATE INDEX blah_t_country_region_idx
ON blah(t, type, country, region);

列的顺序很重要;如果所有查询都使用所有列,它应该从最多到最少选择。否则,您应该更愿意将最常查询使用的列放在最前面。

您可以创建多个索引。 PostgreSQL 有时也可以为单个查询组合多个索引。

请记住,每个索引都有成本 insert/update 并且还使用磁盘 space。

一个选项可能是:

CREATE INDEX blah_t_country_region_idx
ON blah(t, type);

然后在 countryregion 上分离索引。或者多个复合索引,一个t+type+country,一个t+type+region,一个both。这完全取决于您愿意支付多少磁盘 space 和 I/O 成本,以及您的确切查询模式。

在不知道查询模式和有一些查询 explain 数据的情况下提出更详细的策略是不切实际的。

顺便说一句,根据数据源等,您可能希望将国家和地区外键放入查找 table 中,而不是存储文字字符串。