帮你快速理解、总结文档立即下载

timescaledb

最近更新时间:2026-09-16 11:44:01
我的收藏
本文为您介绍 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 TABLE
postgres=> SELECT create_hypertable('metrics', 'time');
create_hypertable
----------------------
(1,public,metrics,t)
(1 row)
返回结果中的 t 表示超表创建成功。

写入时序数据

向超表写入数据的方式与普通表一致:
postgres=> INSERT INTO metrics
SELECT 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_temp
FROM metrics GROUP BY day ORDER BY day LIMIT 7;
day | cnt | avg_temp
------------------------+-----+----------
2026-08-13 08:00:00+08 | 12 | 24.50
2026-08-14 08:00:00+08 | 24 | 24.83
2026-08-15 08:00:00+08 | 24 | 24.17
2026-08-16 08:00:00+08 | 24 | 24.75
2026-08-17 08:00:00+08 | 24 | 24.50
2026-08-18 08:00:00+08 | 24 | 24.25
2026-08-19 08:00:00+08 | 24 | 24.83
(7 rows)
说明:
time_bucket 默认按 UTC 时区分桶,在中国时区(UTC+8)下,按天分桶的边界为每天08:00。如需按本地时区聚合,请先设置会话时区,例如 SET timezone = 'Asia/Shanghai';

首尾值

使用 firstlast 函数获取分组内按时间排序的首尾值:
postgres=> SELECT first(temperature, time) AS first_temp, last(temperature, time) AS last_temp
FROM 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 TABLE
postgres=> 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_partitions
FROM 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_enabled
FROM 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

相关参考