【发布时间】:2011-12-27 17:12:11
【问题描述】:
我必须通过调整基本的 PostgreSQL 服务器配置参数来优化查询。在文档中,我遇到了 work_mem 参数。然后我检查了更改此参数将如何影响我的查询性能(使用排序)。我用各种work_mem 设置测量了查询执行时间,结果非常失望。
我在其上执行查询的表包含 10,000,000 行,并且有 430 MB 的数据要排序。 (Sort Method: external merge Disk: 430112kB)。
使用work_mem = 1MB,EXPLAIN 输出为:
Total runtime: 29950.571 ms (sort takes about 19300 ms).
Sort (cost=4032588.78..4082588.66 rows=19999954 width=8)
(actual time=22577.149..26424.951 rows=20000000 loops=1)
Sort Key: "*SELECT* 1".n
Sort Method: external merge Disk: 430104kB
与work_mem = 5MB:
Total runtime: 36282.729 ms (sort: 25400 ms).
Sort (cost=3485713.78..3535713.66 rows=19999954 width=8)
(actual time=25062.383..33246.561 rows=20000000 loops=1)
Sort Key: "*SELECT* 1".n
Sort Method: external merge Disk: 430104kB
与work_mem = 64MB:
Total runtime: 42566.538 ms (sort: 31000 ms).
Sort (cost=3212276.28..3262276.16 rows=19999954 width=8)
(actual time=28599.611..39454.279 rows=20000000 loops=1)
Sort Key: "*SELECT* 1".n
Sort Method: external merge Disk: 430104kB
谁能解释为什么性能会变差?或者建议任何其他方法通过更改服务器参数来加快查询执行速度?
我的查询(我知道它不是最优的,但我必须对这种查询进行基准测试):
SELECT n
FROM (
SELECT n + 1 AS n FROM table_name
EXCEPT
SELECT n FROM table_name) AS q1
ORDER BY n DESC;
完整的执行计划:
Sort (cost=5805421.81..5830421.75 rows=9999977 width=8) (actual time=30405.682..30405.682 rows=1 loops=1)
Sort Key: q1.n
Sort Method: quicksort Memory: 25kB
-> Subquery Scan q1 (cost=4032588.78..4232588.32 rows=9999977 width=8) (actual time=30405.636..30405.637 rows=1 loops=1)
-> SetOp Except (cost=4032588.78..4132588.55 rows=9999977 width=8) (actual time=30405.634..30405.634 rows=1 loops=1)
-> Sort (cost=4032588.78..4082588.66 rows=19999954 width=8) (actual time=23046.478..27733.020 rows=20000000 loops=1)
Sort Key: "*SELECT* 1".n
Sort Method: external merge Disk: 430104kB
-> Append (cost=0.00..513495.02 rows=19999954 width=8) (actual time=0.040..8191.185 rows=20000000 loops=1)
-> Subquery Scan "*SELECT* 1" (cost=0.00..269247.48 rows=9999977 width=8) (actual time=0.039..3651.506 rows=10000000 loops=1)
-> Seq Scan on table_name (cost=0.00..169247.71 rows=9999977 width=8) (actual time=0.038..2258.323 rows=10000000 loops=1)
-> Subquery Scan "*SELECT* 2" (cost=0.00..244247.54 rows=9999977 width=8) (actual time=0.008..2697.546 rows=10000000 loops=1)
-> Seq Scan on table_name (cost=0.00..144247.77 rows=9999977 width=8) (actual time=0.006..1079.561 rows=10000000 loops=1)
Total runtime: 30496.100 ms
【问题讨论】:
-
在增加 workmem 时,其中一个子查询中是否有另一个合并,从外部合并或嵌套循环或索引循环转移到 hashmap?
-
我已经编辑了我的帖子并包含了查询和执行计划。
-
您的查询与 EXPLAIN ANALYZE 输出不匹配。你使这比它需要的更难。此外,您可能想知道:只有 OP 会自动收到评论提醒。其他人你必须像
@Grzes这样明确地解决。但有一些限制适用。在这里阅读更多:meta.stackexchange.com/questions/43019/… -
@Erwin:不匹配,因为我在查询中更改了表名和参数名。 (我会纠正它)。但查询计划与查询相关。
标签: postgresql postgresql-performance server-configuration