【问题标题】:Multicolum index vs singel column index for time series data in PostgresPostgres中时间序列数据的多列索引与单列索引
【发布时间】:2021-11-08 19:08:10
【问题描述】:

此表开始用于计量表数据的短期存储,然后将被验证并添加到一些长期存储表中。

事实证明,自从我们保存了这些数据后,客户希望将其保留很长时间,而且它正在快速增长。

create table metering_meterreading
(
    id              bigserial                not null.  # Primary Key
    created_at      timestamp with time zone not null,
    updated_at      timestamp with time zone not null,
    timestamp       timestamp with time zone not null,  # BTREE index
    value           numeric(15, 3)           not null,
    meter_device_id uuid                     not null,  # FK to meter_device, BTREE index
    series_id       uuid                     not null   # FK to series, BTREE index
    organization_id uuid                     not null.  # FK to org , BTREE index
);

我计划删除主键,因为 (org_id,meter_device_id,series_id,timestamp) 使它独一无二。它只是由我的 ORM (django) 添加的,当我们开始时我不在乎。

但由于我几乎总是想在组织、仪表设备和系列中进行过滤以获取一系列时间序列数据,我想知道在 (组织 ID、仪表设备 ID、系列 ID、时间戳)上设置多列索引是否更有效) 而不是单独的索引。

我在某处读到,如果我有一个范围,它应该是索引中最右边的。

对于时间序列数据,这仍然不是一个超级高效的表,因为它会变得很大,但我计划通过按范围分区来解决这个问题,或者甚至使用 Timescale。但在分区之前,我希望它尽可能高效地在其中查找数据。

我还在某处看到了一个示例,它使用单独的表格来识别指标:

create table metric
(
    id
    organization_id
    meter_device_id
    series_id
) UNIQE (organization_id, meter_device_id, series_id)
;

create table metering_meterreading
(
    metric_id.      bigserial,  FK to metric, BTREE index
    timestamp       timestamp with time zone not null,  # BTREE index
    value           numeric(15, 3)           not null,
    created_at      timestamp with time zone not null,
    updated_at      timestamp with time zone not null,
);

但我不确定这是否真的比把它们都放在桌子上更好。由于现在涉及另一个表,因此可能会影响摄取率。

【问题讨论】:

    标签: postgresql indexing


    【解决方案1】:

    如果(org_id, meter_device_id, series_id, timestamp)唯一确定一个表行,则需要对所有行使用多列主键。因此,您自动在这些列上有一个 4 列索引。只需确保timestamp 在列表中的最后一个,那么该索引将理想地支持您的查询。

    【讨论】:

    • 是的,那会很好。但问题是 Django ORM 不支持复合主键。所以我现在可能不得不将 id 字段作为主键,以免弄乱 ORM。所以我必须将 id 作为主键,这样我才能对模型进行获取和更新,并对过滤字段有唯一的约束。如果我随后使用 Timescale,这似乎会成为一个问题,我看到人们将时间戳设置为主键,然后将 django 手动生成的约束删除到迁移文件中。 blog.ashtonhudson.com/adding-timescale-to-django.html
    • 另一个 django timescale 实现只是在创建迁移时自动放弃对 id 字段的约束,该字段是 Django 中的标准 pk 字段。 github.com/schlunsen/django-timescaledb/blob/main/timescale/db/…
    • 我会说你应该选择一个更好的 ORM。如果您受到工具的限制并因此不得不选择更糟糕的解决方案,这将是可悲的。
    • 好的。仅仅因为这个就扔掉也太好了。而且这个项目的成本将是疯狂的。所以我想最好的办法是在(org_id,meter_device_id,series_id,timestamp)上设置一个单独的唯一常量,这会给我相同的索引。
    • 对。我知道携带一个额外的索引可能不足以重新考虑基本工具的选择。
    猜你喜欢
    • 2018-07-27
    • 2020-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 2010-09-15
    • 2019-03-22
    相关资源
    最近更新 更多