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

时间:2015-01-23 18:32:29

标签: sql postgresql indexing

假设我们有下表:

我有以下对象:

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

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

  • type
  • country / region(两者,一人或全部)的组合
  • t范围(大多数只是t > tx

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

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

很少有想法:

  1. 将所有字段编码为单个字符串并进行正则表达式查询。例如:encoded = "type;country;v1:n1;v2:n2"。那么,是否可以制作复合索引(t, encoded),这将允许t上的范围查询和encoded上的regexp查询?在这种方法中,我们忽略了索引中的规范范围检查,
  2. 编码jsonb中的所有内容。那么,是否可以在某些jsonb属性上进行索引范围查询?
  3. [编辑]
    广告。 1.可以将这些值放在一个字符串中,而不是将它们放在一个表(tab = {type, country, v1+n1, ...})中,并使用btree_gini扩展名创建gin索引:gin (t timestamp_ops, tab _text_ops)

1 个答案:

答案 0 :(得分:2)

保持简单。使用传统表格和复合索引。

我会看到类似的东西:

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有时也可以为单个查询组合多个索引。

请记住,每个索引都有插入/更新的成本,并且还使用磁盘空间。

一个选项可能是:

CREATE INDEX blah_t_country_region_idx
ON blah(t, type);

然后在countryregion上分隔索引。或多个复合索引,一个在t +类型+国家,一个在t +类型+区域,一个在两者上。这完全取决于您愿意支付多少磁盘空间和I / O成本,以及您的确切查询模式。

在不知道查询模式和查询explain数据的情况下建议更详细的策略并不切合实际。

BTW,根据数据源等,您可能希望将国家和地区外键设置为查找表,而不是存储文字字符串。