我的一个在 Ubuntu 虚拟机上运行 PostgreSQL 14 的数据库出现问题。这个特定的数据库包含一个
timeseries
模式,其中托管一个 meteo
超表(timescaledb 扩展开启)。该数据库的目的是收集瑞士气象站的数据,例如温度、湿度、太阳辐射等。
大多数时候全局性能都很好,但是我无法弄清楚为什么某些特定情况会导致性能显着下降。起初,我认为这是由于表中的数据量所致,但事实似乎并非如此(至少,没有明确的证据表明存在此类问题)。我不是 postgreSQL 专家,因此我在这里寻求您的指导。
这是一个示例查询,可在约 85 毫秒内返回数据:
select count(*) from timeseries.meteo where metadata_id='1089';
count
--------
230765
(1 row)
这是我经过数小时寻找性能问题迹象后发现的麻烦查询。这个特定的查询需要大约 90'000 毫秒来执行(所以大约是前一个查询的 1000 倍):
select count(*) from timeseries.meteo where metadata_id='1019';
count
-------
42668
(1 row)
我上传了这些查询的
EXPLAIN (ANALYZE, BUFFERS)
结果:
我的问题如下:这样一个带有少量数据的“基本”查询如何花费这么多时间,我可以尝试执行哪些操作来提高特定情况下的性能?我的数据库坏了还是怎么的?
感谢您帮助解决这个(神秘)案件。
PS:我检查了 RAM 和 CPU 使用情况,这些似乎不是什么大问题,因为服务器基本上没有得到充分利用。
在 depesz 中找到的真正查询是
select min(time) from timeseries.meteo where metadata_id='1019'
;
这只是经典 ORDER BY...LIMIT 问题的一个非显而易见的演示。问题 id 缺乏时间值较低的行,因此计划需要按时间顺序遍历很长的行序列,然后找到具有合格的metadata_id的行,然后提前停止。
您可以通过
(metadata_id, time)
上的多列索引来解决此问题。然后就可以直接跳转到需要的数据了。