如何提高postgresql查询执行时间

如何提高postgresql查询执行时间

问题陈述:

我们有一个以 Postgresql db 作为后端的企业产品。其中一个表有 5 列,相应的数据类型为 (bigint time、bigint store_time、varchar category、varchar sub_catorgy、integer count)。总共有 1500 万条唯一记录。

客观的:

我们正在尝试在 1 或 2 秒的响应时间内获取/选择约 1400 万条记录以显示在 UI 中。

目前的观察与分析:

我们设计了如下所示的选择语句来获取 1400 万条记录

查询 — “从时间介于 1541156340000 和 1560509940000 之间的表中选择时间、类别、子类别、计数”

时间以纪元 (Epoch) 为单位维护。

表在时间、类别、子类别和计数列上有索引。存储未在任何地方使用的时间列。

在 pgadmin / 同一服务器框 postgres 命令行中运行上述查询时,耗时约 25 秒来检索约 1400 万条记录。

我们尝试了顺序扫描和索引扫描,修改了postgresql.conf文件中的以下参数。两者都花费了相同的 25 秒(没有差异)

尝试 1:

enable_indexscan = on
enable_seqscan = on

尝试2:

enable_indexscan = on
enable_seqscan = off

在使用“EXPLAIN ANALYZE Select Time, category,sub_category,count from table where time between 1541156340000 and 1560509940000”命令分析查询计划时,我们可以看到,总执行时间约为 3-4 秒,而单独运行选择查询(Select Time, category,sub_category,count from table where time between 1541156340000 and 1560509940000)则耗时 25 秒。(不确定,原始选择查询执行时间和“EXPLAIN ANALYZE”执行时间之间的差异是什么。我们假设两者应该相同。- 请确认我们对此理解是否错误)

解释分析输出:


"Seq Scan on table  (cost=0.00..393652.98 rows=13540999 width=52) (actual time=0.007..3346.241 rows=13545864 loops=1)"
"  Filter: ((time >= '1541156340000'::bigint) AND (time <= '1560509940000'::bigint))"
"Planning time: 0.192 ms"
"Execution time: 3733.535 ms"

我们还尝试过在 postgresql 配置文件中更改以下参数,考虑到机器容量(24 核 - 超线程、128 GB RAM、4 TB 磁盘),但仍然没有成功。使用默认参数值也观察到了相同的性能数字。

笔记:
在 128 GB RAM 中,我们的应用程序 JVM 使用 24 GB RAM。应用程序和 Postgresql DB 都位于同一个 JVM 中。在查询执行期间,资源利用率仅正常。

参数调整:


shared_buffers = 6GB
effective_cache_size = 18GB
maintenance_work_mem = 1536MB
checkpoint_completion_target = 0.7
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1
autovacuum = on
seq_page_cost = 1.0
effective_io_concurrency = 200
work_mem = 62914kB
min_wal_size = 1GB
max_wal_size = 2GB

笔记:
查询执行仅耗时 25 秒。查询执行后,我们就能在 UI 中看到结果。因此考虑到这一点,查询结果与在 UI 中显示之间没有延迟。

预期结果

我们期望上述选择查询应在 1 或 2 秒内返回结果。

我们需要一些帮助来调整查询或参数以提高性能。

相关内容