我正在编写一个应用程序来读取嵌入式环境中的实时数据并将其放入PostgreSQL 9.6数据库中。
数据由包含时间戳的元数据的头和包含值的200个无符号字符组成。 200个值是每个值,从头部按照它们在阵列中的位置推断出timsetamp。
根据间隔区分各种测量值,有些测量值每10ms输出一次,其他测量值每100ms输出一次。没有停顿,数据来自FPGA。没有保证金。
我决定构建一个测试平台来检查存储时间序列数据的最佳方式。我的标准是写性能和查询简易性的最佳解决方案。因此,我的测试平台旨在将数据写入一组表,其中包括带有元数据的标题和以下之一: 一个200字节的bytea 一个持有数组的JSON字段(JSONB是首选的hower libpq,但后面会看到) 一系列短裤 ......和 标题& hstore哪个IMHO会有很多重复的数据 离散值 离散值或hstore和继承表。
目前我正在运行前两个,并且认为我会运行一些指标。
代码已经使用了准备好的参数和准备好的语句。
这些指标令人震惊。我在使用3 x nvme M.2 SSD的PostgreSQL 9.6和在SSD的RAID 0中的8个驱动器中的阵列中运行~88次插入/秒,所有这些都设置为具有32Gb RAM和4.2GHz i7的表空间。
我在服务器上重新编译并实现了高达10%的改进。
所以这是放下工具并观察表演,因为它显然不在正确的球场附近。
Research让我尝试将其包含在一笔交易中,这让我有十倍的改进。这有帮助!
我想尝试使用多行插入但我看不到如何使用libpq / libpqtypes执行此操作,是否有人知道如何执行此操作或即使可能?如: -
insert into table values (1,1),
(1,2),
(1,3),
(2,1); -- ... 100 times
WRT到JSONB(JSON有效),我收到以下错误: -
code@snippet:~/src/pg/copy_in$ time ./bulk_load -t -n 1 -h 127.0.0.1 -d fpga_db -u fpga_user
bulk_load.c[186]: PQparamExecPrepared insert didn't go well, PGresult: ERROR: unsupported jsonb version number 91
INSERT INTO packet_test_jsonb (packet_date, module_id, channel_id, frame_count, packet_data) VALUES($1, $2, $3, $4, $5::jsonb)
Aborted (core dumped)
real 0m1.131s
user 0m0.040s
sys 0m0.020s
我在libpqtypes中看不到JSON或JSONB,因此准备好的语句使用VARCHAR $ 5,插入中的强制转换适用于直接JSON。由于我在插入中使用了一个强制转换器,我让服务器决定。
我也看不到如何重复使用我的PQParam。一旦完成了PQparamReset(param),对我来说,如何将值弹出到param而不是使用PQputf并不明显。我认为重复使用可能会让我加速,但我仍在使用PQparamCreate / PQparamClear进行每次使用。
如果没有这一切,我可以使用COPY。我喜欢它的外观但不确定如何将C ++兼容的数据,二进制或不写入C中的“某些缓冲区或文件”。
总结一下: -
(请)我/我如何在libpq / libpqtypes中使用准备好的参数/语句进行多行插入?
如何将一些东西中的东西放到PostgreSQL中的JSONB字段中?我目前创建一个VARCHAR JSON字符串[0,1,2 ... 200]并在插入中强制转换
如何重新使用PQparam?如果你的回复包括多行重复使用,那就更好了;)
您对推断时间戳的时间序列数据的最佳存储格式有什么好的建议吗?
我真的很喜欢示例代码。