工业时序数据存储选型实战:从PostgreSQL到TDengine,查询从15秒到200ms

分享一个工业时序数据存储的选型和迁移实战经验。

场景描述

某3C代工厂,产线上部署了多台视觉检测设备,每台设备每秒钟产生30-50条检测结果。

业务需求:

  1. 查询任意7天的良率趋势,响应时间1秒以内

  2. 查询某一批次产品的所有检测记录,响应时间500ms以内

  3. 数据保留周期1年

初始方案及问题

最初用PostgreSQL存储。表结构包含时间、产品ID、缺陷类型、判定结果等字段。

数据量达到500万条时,问题暴露:

  • 7天趋势查询(约80万条)响应时间从200ms退化到15秒

  • 批量插入性能从5000条/秒降至2000条/秒

  • 索引膨胀,存储空间从预期50GB增长到100GB+

尝试了索引优化、分区表、SQL优化,效果有限。

原因分析

检测数据是典型的时间序列数据------按时间写入、按时间查询、极少更新。PostgreSQL的存储引擎为通用事务场景设计,不是为高频时序写入+范围查询优化的。

选型对比

|--------------|------------|----------|
| 对比维度 | PostgreSQL | TDengine |
| 写入速度(条/秒) | 5000 | 30000+ |
| 7天趋势查询 | 15秒 | 200ms |
| 单批次查询(1000条) | 50ms | 20ms |
| 存储空间(500万条) | 100GB | 40GB |

TDengine优势:列式存储+时序索引,内置降采样和聚合函数,高压缩比。

迁移方案

渐进式迁移:

  1. 历史数据保留在PostgreSQL,用于长期归档

  2. 新数据(7天内)写入TDengine,用于实时分析

  3. 查询层做路由:7天内走TDengine,7天以上走PostgreSQL

核心代码示意:

public class DataQueryService {

public List<TrendData> queryTrend(Date start, Date end) {

long daysBetween = ChronoUnit.DAYS.between(start, end);

if (daysBetween <= 7) {

return tdEngineDao.queryTrend(start, end);

} else {

return pgDao.queryTrend(start, end);

}

}

}

上线效果

  • 7天趋势查询响应:15秒 → 200ms

  • 存储空间:100GB → 40GB(减少60%)

  • 写入性能:2000条/秒 → 30000条/秒

踩坑提醒

⚠️ TDengine SQL语法与PostgreSQL有差异,迁移时注意函数替换

⚠️ 分区键设计要合理,避免单表数据过大

⚠️ 历史数据迁移建议分批执行,避免一次性写入压力

欢迎在评论区交流你的实战经验,我们一起探讨~

相关推荐
隔窗听雨眠37 分钟前
云数仓向PostgreSQL生态延伸的技术动因与工程代价
postgresql·数据库架构·云数仓
codigger1 小时前
线上数据库连接池打满:从应急止损到架构根治的完整方案
数据库·sql·程序员
倔强的石头_1 小时前
集中式与分布式怎么选?我把手头11套系统重新过了一遍秤
数据库
挖掘狂人1 小时前
线上数据库连接池打满:从应急止损到架构根治的完整方案
数据库·sql·程序员
Rainmicro1 小时前
【无标题】
java·数据库·算法
Thanks_ks2 小时前
MySQL 的索引是什么?用图书馆的目录讲明白
数据库·sql·mysql·索引·联合索引·explain·慢查询优化
CoderYanger8 小时前
Java EE 进阶:8.MyBatis 操作数据库(入门)(第二弹)
java·数据库·spring boot·spring·面试·java-ee·mybatis
wafrdggh10 小时前
2026电商快递批量查询怎么用?固乔助手模板设置评测
大数据·数据库·小程序
一个天蝎座 白勺 程序猿11 小时前
KingbaseES数据库归档重做日志文件管理:从配置到运维的实战指南
运维·数据库·oracle·kingbasees·金仓数据库
龙腾AI白云14 小时前
仿真到现实(Sim-to-Real)迁移:跨越仿真与现实鸿沟
数据库·机器学习·plotly·知识图谱·tornado