Timescale Cloud:扩展版、企业版

自托管产品

MST

一旦不常用的数据被分层并迁移到对象存储层,通过启用 timescaledb.enable_tiered_reads GUC,仍然可以使用标准 SQL 进行查询。默认情况下,该 GUC 设置为 false,因此查询不会触及分层数据。

timescaledb.enable_tiered_reads GUC,或称 Grand Unified Configuration 变量,是一个控制是否查询分层数据的设置。该配置变量可以在不同级别设置,包括对整个数据库服务器全局设置、对单个数据库设置以及对单个会话设置。

启用分层读取后,即使您的数据分布在不同的存储层中,您也可以正常查询数据。您的超表分布在各个层中,因此查询和 JOIN 操作都可以正常工作并像往常一样获取相同的数据。

默认情况下,查询不会访问分层数据。查询分层数据可能会降低查询性能,因为数据未本地存储在 Timescale 的高性能存储层上。请参阅性能注意事项

  1. 在查询包含分层数据的超表之前启用 timescaledb.enable_tiered_reads,并在完成后重置它

    set timescaledb.enable_tiered_reads = true; SELECT count(*) FROM example; set timescaledb.enable_tiered_reads = false;

    这会查询所有数据块中的数据,包括分层数据块和非分层数据块

    ||count|
    |---|
    |1000|

通过在会话中启用 timescaledb.enable_tiered_reads,可以使会话中的所有未来查询都使用对象存储层。

  1. 为整个会话启用 timescaledb.enable_tiered_reads

    set timescaledb.enable_tiered_reads = true;

    该会话中的所有未来查询都配置为从分层数据和本地存储数据中读取。

您还可以按照以下步骤始终启用查询从分层数据中读取

  1. 为所有未来会话启用 timescaledb.enable_tiered_reads

    alter database tsdb set timescaledb.enable_tiered_reads = true;

    在所有未来创建的会话中,timescaledb.enable_tiered_reads 将初始化为 enabled

本节将说明分层存储查询的工作原理。

考虑一个包含标准 devices 表和 metrics 超表的简单数据库。启用分层存储后,您可以看到哪些数据块已分层到对象存储层。

chunk_name | range_start | range_end
------------------+------------------------+------------------------
_hyper_2_4_chunk | 2015-12-31 00:00:00+00 | 2016-01-07 00:00:00+00
_hyper_2_3_chunk | 2017-08-17 00:00:00+00 | 2017-08-24 00:00:00+00
(2 rows)

以下查询仅从对象存储层获取数据。这基于查询指定的 WHERE 子句和此超表上方列出的数据块范围是合理的。

EXPLAIN SELECT * FROM metrics where ts < '2017-01-01 00:00+00';
QUERY PLAN
---------------------------------------------------------------------
Foreign Scan on osm_chunk_2 (cost=0.00..0.00 rows=2 width=20)
Filter: (ts < '2017-01-01 00:00:00'::timestamp without time zone)
Match tiered objects: 1
Row Groups:
_timescaledb_internal._hyper_2_4_chunk: 0
(5 rows)

如果您的查询不需要触及对象存储层,它将只处理标准存储中的数据块。以下查询涉及尚未分层到对象存储层的较新数据。计划中的 Match tiered objects :0 表示没有分层数据与查询约束匹配。因此,对象存储中的数据完全未被触及。

EXPLAIN SELECT * FROM metrics where ts > '2022-01-01 00:00+00';
QUERY PLAN
--------------------------------------------------------------------------------
----------------------------------
Append (cost=0.15..25.02 rows=568 width=20)
-> Index Scan using _hyper_2_5_chunk_metrics_ts_idx on _hyper_2_5_chunk (co
st=0.15..22.18 rows=567 width=20)
Index Cond: (ts > '2022-01-01 00:00:00'::timestamp without time zone)
-> Foreign Scan on osm_chunk_2 (cost=0.00..0.00 rows=1 width=20)
Filter: (ts > '2022-01-01 00:00:00'::timestamp without time zone)
Match tiered objects: 0
Row Groups:
(7 rows)

这是另一个不触及分层数据的 JOIN 示例

EXPLAIN SELECT ts, device_id, description FROM metrics
JOIN devices ON metrics.device_id = devices.id
WHERE metrics.ts > '2023-08-01';
QUERY PLAN
--------------------------------------------------------------------------------
Hash Join (cost=32.12..184.55 rows=3607 width=44)
Hash Cond: (devices.id = _hyper_4_9_chunk.device_id)
-> Seq Scan on devices (cost=0.00..22.70 rows=1270 width=36)
-> Hash (cost=25.02..25.02 rows=568 width=12)
-> Append (cost=0.15..25.02 rows=568 width=12)
-> Index Scan using _hyper_4_9_chunk_metrics_ts_idx on _hyper_4_
9_chunk (cost=0.15..22.18 rows=567 width=12)
Index Cond: (ts > '2023-08-01 00:00:00+00'::timestamp with
time zone)
-> Foreign Scan on osm_chunk_3 (cost=0.00..0.00 rows=1 width=12
)
Filter: (ts > '2023-08-01 00:00:00+00'::timestamp with time
zone)
Match tiered objects: 0
Row Groups:
(11 rows)

对分层数据的查询预计会比对本地数据的查询慢。然而,在少数情况下,分层读取也可能影响本地数据的查询规划时间。为了防止应用程序查询出现任何意外的性能下降,我们将 GUC timescaledb.enable_tiered_reads 设置为 false

  • 未指定时间边界的查询在查询分层数据时,预计在查询规划和查询执行期间都会表现较慢。在这种情况下,Timescale 的数据块排除算法无法应用。

    SELECT * FROM device_readings WHERE id = 10;
  • 带有在运行时计算的谓词(例如 NOW())的查询在规划时并非总是被优化,因此在查询对象存储层时,其性能可能比静态分配的值慢。

    例如,此查询在规划时被优化

    SELECT * FROM metrics WHERE ts > '2023-01-01' AND ts < '2023-02-01'

    以下查询在查询规划时不会进行数据块修剪

    SELECT * FROM metrics WHERE ts < now() - '10 days':: interval

    目前,当查询优化器可以应用规划时优化时,对分层数据的查询效果最佳。

  • 查询分层数据时,文本和非原生类型(JSON、JSONB、GIS)的过滤速度较慢。

关键词

在此页上发现问题?报告问题 或 编辑此页 在 GitHub 上。