本文为您介绍 timescaledb 插件的简介及使用方法。
概述
timescaledb 是时序数据库插件,将普通表扩展为按时间自动分片的超表,支持高效写入和时序聚合查询,适用于监控、物联网、金融行情等时序场景。
支持版本
PostgreSQL 版本 | 内核版本 |
PostgreSQL 10 | v10.23_r1.20及以上 |
PostgreSQL 11 | v11.22_r1.35及以上 |
PostgreSQL 12 | v12.22_r1.37及以上 |
PostgreSQL 13 | v13.22_r1.32及以上 |
PostgreSQL 14 | v14.22_r1.42及以上 |
PostgreSQL 15 | v15.14_r1.27及以上 |
PostgreSQL 16 | v16.14_r1.26及以上 |
PostgreSQL 17 | v17.10_r1.22及以上 |
PostgreSQL 18 | v18.3_r1.6及以上 |
说明:
您可在控制台实例详情页查看当前实例的内核版本,或执行
SHOW tencentdb_version; 查询。插件简介
timescaledb 在 PostgreSQL 的基础上提供时序数据管理能力:通过超表(hypertable)将数据按时间自动切分为多个分片(chunk),配合时间分桶函数(time_bucket)进行时序聚合,并提供首尾值、直方图等时序聚合函数,提升时序数据的写入和查询性能。
环境准备
加载插件
timescaledb 是需要预加载的插件,使用前请先在控制台参数设置的
shared_preload_libraries 参数中勾选 timescaledb,保存后重启实例。参数设置方法可参考 设置实例参数。创建扩展
连接到需要使用的数据库,执行以下语句创建扩展:
postgres=> CREATE EXTENSION timescaledb;CREATE EXTENSION
创建超表
先创建普通表,再使用
create_hypertable 将其转换为超表,第二个参数为时间列:postgres=> CREATE TABLE metrics (time timestamptz NOT NULL,device_id int,temperature float);CREATE TABLEpostgres=> SELECT create_hypertable('metrics', 'time');create_hypertable----------------------(1,public,metrics,t)(1 row)
返回结果中的
t 表示超表创建成功。写入时序数据
向超表写入数据的方式与普通表一致:
postgres=> INSERT INTO metricsSELECT now() - interval '1 hour' * i, i % 3, 20 + (i % 10)FROM generate_series(0, 500) AS i;INSERT 0 501
时序聚合查询
按时间分桶
使用
time_bucket 函数按时间分桶进行聚合。以下示例按天统计温度的平均值:postgres=> SELECT time_bucket('1 day', time) AS day, count(*) AS cnt, round(avg(temperature)::numeric, 2) AS avg_tempFROM metrics GROUP BY day ORDER BY day LIMIT 7;day | cnt | avg_temp------------------------+-----+----------2026-08-13 08:00:00+08 | 12 | 24.502026-08-14 08:00:00+08 | 24 | 24.832026-08-15 08:00:00+08 | 24 | 24.172026-08-16 08:00:00+08 | 24 | 24.752026-08-17 08:00:00+08 | 24 | 24.502026-08-18 08:00:00+08 | 24 | 24.252026-08-19 08:00:00+08 | 24 | 24.83(7 rows)
说明:
time_bucket 默认按 UTC 时区分桶,在中国时区(UTC+8)下,按天分桶的边界为每天08:00。如需按本地时区聚合,请先设置会话时区,例如 SET timezone = 'Asia/Shanghai';。首尾值
使用
first 和 last 函数获取分组内按时间排序的首尾值:postgres=> SELECT first(temperature, time) AS first_temp, last(temperature, time) AS last_tempFROM metrics WHERE device_id = 0;first_temp | last_temp------------+-----------28 | 20(1 row)
说明:
first(temperature, time) 返回该组内时间最早的温度值,last(temperature, time) 返回时间最晚的值。直方图
使用
histogram 函数按区间统计数值分布:postgres=> SELECT histogram(temperature, 0, 30, 5) FROM metrics;histogram---------------------{0,0,0,0,201,300,0}(1 row)
说明:
histogram(value, min, max, nbuckets) 将 [min, max] 等分为 nbuckets 个桶,并返回长度为 nbuckets+2 的数组:第1个元素为小于 min 的计数(下溢),最后1个元素为大于 max 的计数(上溢),中间 nbuckets 个为各桶计数。上述结果中501条数据分别落在两个温度区间,其中201条落在18至24度区间、300条落在24至30度区间。分片管理
查看分片
使用
show_chunks 函数查看超表的分片:postgres=> SELECT show_chunks('metrics');show_chunks----------------------------------------_timescaledb_internal._hyper_1_1_chunk_timescaledb_internal._hyper_1_2_chunk_timescaledb_internal._hyper_1_3_chunk_timescaledb_internal._hyper_1_4_chunk(4 rows)
说明:
数据按时间自动切分为4个 chunk。
查看分片大小
使用
chunks_detailed_size 函数查看各分片占用的空间:postgres=> SELECT chunk_name, total_bytes FROM chunks_detailed_size('metrics') ORDER BY chunk_name;chunk_name | total_bytes------------------+-------------_hyper_1_1_chunk | 24576_hyper_1_2_chunk | 57344_hyper_1_3_chunk | 57344_hyper_1_4_chunk | 24576(4 rows)
删除过期分片
使用
drop_chunks 函数删除指定时间之前的分片:postgres=> SELECT drop_chunks('metrics', older_than => now() - interval '2 days');drop_chunks----------------------------------------_timescaledb_internal._hyper_1_3_chunk_timescaledb_internal._hyper_1_4_chunk(2 rows)
函数返回被删除的分片列表。删除后再查看剩余分片:
postgres=> SELECT show_chunks('metrics');show_chunks----------------------------------------_timescaledb_internal._hyper_1_1_chunk_timescaledb_internal._hyper_1_2_chunk(2 rows)
设置分片时间间隔
使用
set_chunk_time_interval 函数设置超表的分片时间跨度:postgres=> SELECT set_chunk_time_interval('metrics', interval '1 day');set_chunk_time_interval-------------------------(1 row)
说明:
设置后,后续新写入的数据将按每天一个 chunk 的粒度切分;已存在的 chunk 保持原间隔不变。合理的分片间隔可兼顾写入性能与查询效率。
多维度分区
对于既需要按时间、又需要按其他维度(如设备、地域)分区查询的场景,可使用
add_dimension 添加空间分区:postgres=> CREATE TABLE tracking (time timestamptz NOT NULL,location_id int,temp float);CREATE TABLEpostgres=> SELECT create_hypertable('tracking', 'time');create_hypertable-----------------------(2,public,tracking,t)(1 row)postgres=> SELECT add_dimension('tracking', 'location_id', number_partitions => 4);add_dimension-----------------------------------(3,public,tracking,location_id,t)(1 row)
查看维度信息:
postgres=> SELECT dimension_number, column_name, dimension_type, num_partitionsFROM timescaledb_information.dimensions WHERE hypertable_name = 'tracking' ORDER BY dimension_number;dimension_number | column_name | dimension_type | num_partitions------------------+-------------+----------------+----------------1 | time | Time |2 | location_id | Space | 4(2 rows)
说明:
超表现在按
time 时间维度和 location_id 空间维度进行分区,location_id 被划分为4个分区。查看超表信息
查看超表大小
使用
hypertable_size 函数查看超表占用的空间:postgres=> SELECT pg_size_pretty(hypertable_size('metrics')) AS size;size-------88 kB(1 row)
查看超表元数据
通过
timescaledb_information.hypertables 视图查看超表信息:postgres=> SELECT hypertable_name, num_chunks, compression_enabledFROM timescaledb_information.hypertables WHERE hypertable_name = 'metrics';hypertable_name | num_chunks | compression_enabled-----------------+------------+---------------------metrics | 2 | f(1 row)
说明:
删除过期分片后,
num_chunks 为2,与 show_chunks 的结果一致。常见问题
Q:创建扩展时报 must be preloaded?
A:timescaledb 需要预加载。请在控制台参数设置的
shared_preload_libraries 参数中勾选 timescaledb,保存并重启实例后再创建扩展。Q:连续聚合(continuous aggregate)、压缩(compression)、保留策略(retention policy)不可用?
A:腾讯云提供的 timescaledb 为 Apache 2.0版本,连续聚合、压缩、数据保留策略等 Timescale License 功能不在支持范围内,使用时会提示
not supported under the current "apache" license。