【问题标题】:High speed single row inserts with PostgreSQL & TimescaleDB使用 PostgreSQL 和 TimescaleDB 进行高速单行插入
【发布时间】:2020-11-12 21:02:40
【问题描述】:

我有一个 TSDB Hypertable 的案例,看起来大致如下:

CREATE TABLE data (
  pool_id INTEGER NOT NULL,
  ts TIMESTAMP NOT NULL,
  noise_err DECIMAL,
  noise_val DECIMAL,
  signal_err DECIMAL,
  signal_val DECIMAL,
  high_val DECIMAL,
  low_val DECIMAL,

  CONSTRAINT data_pid_fk FOREIGN KEY (pool_id) REFERENCES pools (id) ON DELETE CASCADE
);

CREATE UNIQUE INDEX data_pts_idx ON data (pool_id, ts);
SELECT create_hypertable('data', 'ts', 'pool_id', 100);

大约有 1000 个池,data 包含每个池超过 1 年的分钟记录,并且有相当多的分析查询处理过去 3 到 5 天的数据。新数据的到来有任意延迟:10 毫秒到 30 秒,具体取决于池。

现在的问题是:我需要在收到新记录后尽快运行分析查询,因此我无法批量插入,我需要加快单行插入速度。

我运行了timescaledb-tune,然后关闭了同步提交 (synchronous_commit = off),使用了unlogged 表模式,并尝试禁用自动清理,但没有多大帮助。 我得到的最佳插入时间约为 37 毫秒,当并发插入开始到 110 毫秒时会降级。

除了删除索引/约束,我还能做些什么来加快单行插入?

【问题讨论】:

  • 空间分区会降低性能。使用100个分区的空间分区的原因是什么?
  • @a_horse_with_no_name 我使用的是 PG 版本 12。
  • @k_rus 的重点是在 RAM 中保留尽可能多的数据,因此所有池的最后一周始终在 RAM 中。
  • 使用标准系统工具查看瓶颈在哪里。 topsarvmstat。另外,对 pg_stat_activity 的 wait_event 字段进行采样。

标签: postgresql performance postgresql-12 timescaledb data-ingestion


【解决方案1】:

首先,为什么首先对这个表使用 timescaledb?你从中得到了什么值得放慢速度的东西?

其次,您每年有 5200 个分区的数据。这接近于无法管理的分区数量。

【讨论】:

  • 该项目已经在使用 PGSQL 作为主数据库,当需要存储时间序列数据时,使用 TSDB 就很容易了。 W/o 单次写入最多需要 1 秒的并发写入。这么多分区的目的是将每个池的最后一周保留在 RAM 中。
  • 1 秒做单行插入是很奇怪的。您是否有数百个索引没有告诉我们?
  • @Daniel "这么多分区的目的是将每个池的最后一周保留在 RAM 中" pool_id 上的分区对此有何帮助?
  • 不,表格按原样显示。当我有 10 多个并行插入时,它就开始了
  • 我的想法是 PG 会尽可能多地保存在 RAM 中,所以我已经切碎了那么多数据。
【解决方案2】:

我质疑需要查看最新瞬间数据的分析查询的要求。

无论如何,加快单行插入的方法是:

  • synchronous_commit 设置为off

    但请注意,这意味着在发生崩溃时,大约半秒的已提交事务的数据丢失!如果这是不可接受的,请使用commit_siblingscommit_delay;这也将减少 WAL 刷新的次数。

  • 使用准备好的语句。使用单行插入,计划时间会很长。

  • 除非您不介意在崩溃后丢失数据,否则不要使用未记录的表。

  • 不要禁用 autovacuum。

  • 增加max_wal_size 以获取不超过健康的检查点。

【讨论】:

猜你喜欢
  • 2014-01-15
  • 1970-01-01
  • 2020-02-01
  • 2019-03-04
  • 1970-01-01
  • 2011-07-15
  • 2021-09-26
  • 1970-01-01
  • 2013-09-30
相关资源
最近更新 更多