【问题标题】:What's the best index for a json fields checking and fields range queries什么是 json 字段检查和字段范围查询的最佳索引
【发布时间】:2015-01-24 23:25:21
【问题描述】:

假设我们有下表:

我有以下对象:

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 的正则表达式查询?在这种方法中,我们忽略了索引中的规范范围检查,
  2. jsonb 中的所有内容进行编码。那么,是否可以对一些jsonb属性进行索引范围查询呢?

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

【问题讨论】:

  • 什么禁止你使用一个包含 5 个字段和经典索引的简单 Tick 表?
  • 在“经典”索引中:(a,b,c,d) 如果不同时指定 ab,我将无法查询 c

标签: sql postgresql indexing


【解决方案1】:

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

我会看类似的东西:

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+type+country 上,一个在 t+type+region 上,一个在两者上。这完全取决于您愿意支付多少磁盘空间和 I/O 成本,以及您的确切查询模式。

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

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

【讨论】:

  • 我正在考虑这种方法,但它不符合我的要求:我需要对t 进行范围查询,而其他一些字段可能是可选的。在基本的 btree 复合索引中,只能查询最后一个参数的范围。在这种方法中,我需要构建很多“基本”索引(实际上我有 2 个文本字段,然后是国家和地区)。我想知道是否有更好的方法。
  • @RobertZaremba 我已经概述了一个替代方案 - 一个公共基础索引加上每个单独属性的索引。然后 Pg 可以进行位图索引扫描。它没有那么快并且不能使用仅索引扫描,但需要更少和更小(因此扫描速度更快)的索引。顺便说一句,(a,b,c) Pg 实际上可以使用它来查询 a,c 或 b,c - 它只是速度较慢,因此 Pg 不太可能选择它。
  • 是的,但我不需要建立 5 个索引。我想知道是否有 - 例如有一些特定于查询的额外字段并将其与一些 gin 索引一起使用。除此之外,国家/地区外键的想法非常好。
  • @RobertZaremba 我希望您会发现这种方法更慢,而不是更快。中缀搜索很慢。数组索引很大并且更新缓慢。以此类推。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-28
  • 2014-01-12
  • 1970-01-01
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多