我的postgresql数据库出现轻微问题,读取时间爆炸。
背景资料:
两个表,两个表只有4列:uuid(uuid),timestamp(bigint),type(text)和value(double)在一个,值(double [])在另一个。 (是的,我想把它合并到一张桌子里......对此的决定不在我手中)。
鉴于每个“项目”只需要相当少量的保留数据,我已经将所需数据复制到专用于每个项目的表中。现在,有趣的部分开始,当我尝试读取数据时:
CREATE TABLE fake_timeseries1
(
"timestamp" bigint,
uuid uuid,
value double precision,
type text COLLATE "default".pg_catalog
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
ALTER TABLE fake_timeseries1
OWNER to user;
CREATE INDEX fake_timeseries1_timestamp_idx
ON fake_timeseries1 USING btree
(timestamp)
TABLESPACE pg_default;
ALTER TABLE fake_timeseries1
CLUSTER ON fake_timeseries1_timestamp_idx;
从那张临时表中我做到了:
"SELECT * FROM table_name WHERE timestamp BETWEEN ? AND ? ;"
很简单,应该工作得相当快,对吧?错误。
目前我正在测试小批量(只有x * 40k行,返回25%)。
对于10k行,它只需要6秒,20k已经是34秒,而对于40k行(仅仅160k),每桌需要3分钟......仅需6分钟就可以获得6Mb数据。 (是的,我们处于gb线,所以它可能没有瓶颈)
我已经尝试在时间戳上使用索引和群集,但这确实会减慢速度。有趣的是,不是在创建临时表,而是在读取数据时。
我该怎么做才能加快阅读过程?它需要能够在不超过5分钟(最好不到1分钟)的时间内从不超过160k行的表中读取这些10-50k行,而是数千万。
什么可能导致简单选择与首先创建整个表格一样慢? (阅读3分钟,创建3.5分钟)。
提前谢谢。
希望分析(80k中的20k):
"Execution Time": 27.501,
"Planning Time": 0.514,
"Plan": {
"Filter": "((\"timestamp\" >= '1483224970970'::bigint) AND (\"timestamp\" <= '1483232170970'::bigint))",
"Node Type": "Seq Scan",
"Relation Name": "fake_timeseries1",
"Alias": "fake_timeseries1",
"Actual Rows": 79552,
"Rows Removed by Filter": 0,
"Actual Loops": 1
},
"Triggers": []
实际执行时间为34.047秒。
更新:
继续使用不同的测试数据集进行测试。以下是一个非常大的测试集的分析,其中我只读取了0.25%的数据...仍然使用seq扫描。有人有想法吗?
[
{
"Execution Time": 7121.59,
"Planning Time": 0.124,
"Plan": {
"Filter": "((\"timestamp\" >= '1483224200000'::bigint) AND (\"timestamp\" <= '1483233200000'::bigint))",
"Node Type": "Seq Scan",
"Relation Name": "fake_forecast",
"Alias": "fake_forecast",
"Actual Rows": 171859,
"Rows Removed by Filter": 67490381,
"Actual Loops": 1
},
"Triggers": []
}
]
更新:经过更多测试后,在第二个PostgresQL数据库上,似乎我不知何故已经达到了硬盘上限。
无论我做什么,我能得到的最大值是每秒这两张桌子的3.3k行。只有当我使用大批量调用20-80k行的最佳点时才会这样。其中需要6分。即使在我自己的机器上的数据库上也是24秒。
有没有什么可以做的(除了更好的硬件)来加快这个速度?