问题描述
我尝试了插入查询性能测试。这是数字:-
Postgres
插入:平均执行时间10次插入1百万行的时间:6260毫秒
时间刻度
插入:平均执行时间10次插入1百万行:10778 ms
插入查询:
-- Testing SQL Queries
--Join table
CREATE TABLE public.sensors(
id SERIAL PRIMARY KEY,type VARCHAR(50),location VARCHAR(50)
);
-- Postgres table
CREATE TABLE sensor_data (
time TIMESTAMPTZ NOT NULL,sensor_id INTEGER,temperature DOUBLE PRECISION,cpu DOUBLE PRECISION,FOREIGN KEY (sensor_id) REFERENCES sensors (id)
);
CREATE INDEX idx_sensor_id
ON sensor_data(sensor_id);
-- TimescaleDB table
CREATE TABLE sensor_data_ts (
time TIMESTAMPTZ NOT NULL,FOREIGN KEY (sensor_id) REFERENCES sensors (id)
);
SELECT create_hypertable('sensor_data_ts','time');
-- Insert Data
INSERT INTO sensors (type,location) VALUES
('a','floor'),('a','ceiling'),('b','ceiling');
-- Postgres
EXPLAIN ANALYSE
INSERT INTO sensor_data (time,sensor_id,cpu,temperature)
SELECT
time,random() AS cpu,random()*100 AS temperature
FROM generate_series(now() - interval '125 week',now(),interval '5 minute') AS g1(time),generate_series(1,4,1) AS g2(sensor_id);
-- TimescaleDB
EXPLAIN ANALYSE
INSERT INTO sensor_data_ts (time,1) AS g2(sensor_id);
我是否忽略了任何优化?
解决方法
默认情况下,超表每周创建一个块(可在create_hypertable
调用中配置)。因此,使用上述设置,您为TimescaleDB创建了125个块,每个块有8000行。此块创建以及处理此逻辑的开销很大。因此,在数据集如此之小的情况下,您会看到此块创建的开销,通常会在更大的数据集上摊销:在大多数“自然”设置中,我们通常会看到数百万以上(或至少100,000s)的数量)每块的行数。
当数据集(尤其是当前正在维护的索引)自然不适合内存时,您开始看到的分区结构(如TimescaleDB)和单个表之间的插入性能差异也就出现了。
在上面,1M行很容易容纳在内存中,并且在原始PG表上唯一的索引是sensor_id,因此它很小。 (在TimescaleDB超表上,默认情况下,您在时间戳上有索引,每个块都有索引,因此实际上您有125个索引,给定不同的时间戳,每个索引的大小为8000。)
有关视觉效果,请参见以下较早的博客文章:https://blog.timescale.com/blog/time-series-data-why-and-how-to-use-a-relational-database-instead-of-nosql-d0cd6975e87c/#result-15x-improvement-in-insert-rate
Note插入到单个PG表的开始大约是相同的,但是随着表变大并且数据/索引开始交换到磁盘而消失。
如果您想进行更大的性能测试,建议您尝试使用时间序列基准套件:https://github.com/timescale/tsbs
,在运行于Docker的TimescaleDB版本1.7中,使用https://github.com/vincev/tsdbperf可以每秒在我的笔记本电脑上插入约60万行:
$ ./tsdbperf --workers 8 --measurements 200000
[2020-11-03T20:25:48Z INFO tsdbperf] Number of workers: 8
[2020-11-03T20:25:48Z INFO tsdbperf] Devices per worker: 10
[2020-11-03T20:25:48Z INFO tsdbperf] Metrics per device: 10
[2020-11-03T20:25:48Z INFO tsdbperf] Measurements per device: 200000
[2020-11-03T20:26:15Z INFO tsdbperf] Wrote 16000000 measurements in 26.55 seconds
[2020-11-03T20:26:15Z INFO tsdbperf] Wrote 602750 measurements per second
[2020-11-03T20:26:15Z INFO tsdbperf] Wrote 6027500 metrics per second