1

为了提高性能,我调整了参数 shared_buffers 和 work_mem。尽管我尝试了上述参数的不同组合,但我的查询花费了相同的时间。每当更改“shared_buffer”时,我都会重新启动服务器我的环境是

Postgres 9.1 操作系统 Windows 7 内存 8GB

我尝试了 1gb、2gb 和 3gb 的 shared_buffers。但是查询执行时间变化很小(以毫秒为单位)

我正在给出查询的解释计划

GroupAggregate  (cost=11100.99..12737.10 rows=50342 width=24) (actual time=181.789..268.733 rows=49829 loops=1)
  ->  Sort  (cost=11100.99..11226.84 rows=50342 width=24) (actual time=181.761..188.323 rows=50000 loops=1)    
        Sort Key: (date(t_proof_of_play.play_timestamp)), (date_trunc(''hour''::text, t_proof_of_play.play_timestamp)), t_device_endpoint.venue_hierarchy_id, t_device_endpoint.device_config_id, t_proof_of_play.asset_id
        Sort Method: quicksort  Memory: 5443kB
        ->  Hash Join  (cost=2629.37..7169.41 rows=50342 width=24) (actual time=15.416..112.175 rows=50000 loops=1)
              Hash Cond: (t_proof_of_play.device_endpoint_id = t_device_endpoint.id)
              ->  Bitmap Heap Scan on t_proof_of_play  (cost=2628.28..6224.41 rows=50342 width=20) (actual time=15.332..29.004 rows=50000 loops=1
                    Recheck Cond: ((is_processed = 0) AND (is_revenue = 1))
                    -> Bitmap Index Scan on process_revenue  (cost=0.00..2615.69 rows=50342 width=0) (actual time=15.081..15.081 rows=50000 loops=1)
                          Index Cond: ((is_processed = 0) AND (is_revenue = 1))
              ->   Hash  (cost=1.04..1.04 rows=4 width=12) (actual time=0.026..0.026 rows=4 loops=1)
                    Buckets: 1024  Batches: 1  Memory Usage: 1kB
                    ->  Seq Scan on t_device_endpoint  (cost=0.00..1.04 rows=4 width=12) (actual time=0.009..0.015 rows=4 loops=1)
Total runtime: 276.027 ms

explain.depesz 上的表格版本

欢迎提出建议。提前致谢

问候

4

3 回答 3

3

正如@RichardHuxton 指出的那样,您以每行大约 5 微秒的速度检索结果。很难对此抱怨太多。但是这个比率证明你有一个非常高的缓存命中率。您可能想尝试调整连接上的成本因素以反映这一点(使用SET命令),然后再次尝试查询以查看是否获得了更好的计划。

SET cpu_tuple_cost = 0.03;
SET random_page_cost = 1;
SET effective_cache_size = '4GB';
-- (your query here)

当然,@regilero 是正确的shared_buffers——在 Windows 上它必须保持小

即使是相当简单的查询,每个结果行花费的时间也很少少于 2 微秒,因此对于具有连接、排序和聚合的查询,您没有很大的改进空间。

于 2013-10-15T18:10:34.617 回答
2

从原始的解释中挑选出重要的数字可能很困难。幸运的是,一位长期的社区成员为我们构建了一个有用的工具来将其制表 - 我添加了一个指向 depesz.com 的链接。

首先,我看不到更改 shared_buffers 会对任何特定查询产生任何影响,而且无论如何您都没有提供值。更改机器上内存使用的总体平衡是一个通用值。您将根据整体工作负载而不是特定查询对其进行调整。

查询的三个主要部分是连接、排序和聚合。这似乎是合理的。

我不知道您正在运行什么聚合(您没有提供查询)。大概你在 play_timestamp 上总结了一天/小时(基于排序)。你需要两个级别吗?

对于您相当详细的排序(5 列,两列基于函数调用),只要work_mem对排序足够大,就没有什么可做的了。

所以 - 我们也许可以改进连接。部分索引可能会有所帮助。就像是:

CREATE INDEX idx1 ON t_proof_of_play (device_endpoint_id) WHERE is_processed=0 AND is_revenue=1

当然,没有什么是免费的,每次更新时您都将支付此索引的维护费用t_proof_of_play

即便如此,如果你将加入时间减半,那只会将总时间从 276 毫秒减少到大约 235 毫秒。您在大约 0.25 秒内处理 50,000 行 - 每行 5 微秒。

于 2013-10-15T09:09:47.870 回答
1

作为对@Richard Huxton 回答的补充。

如Windows文档中所述,您不能使用大量shared_buffers

此外,在 Windows 上,较大的 shared_buffers 值也没有那么有效。您可能会发现保持设置相对较低并更多地使用操作系统缓存会获得更好的结果。Windows 系统上 shared_buffers 的有用范围一般为 64MB 到 512MB。

所以你应该将此参数设置为 512MB,PostgreSQL 将无法在 Windows 上使用更多共享内存来优化他的内存使用。在我看来,Windows 不是 PostgreSQL 服务器的最佳操作系统,无论如何你也可以尝试调整effective_cache_size到 50% 或 75% 的可用内存(所以可能是 2GB 或 4GB)。这是对 PostgreSQL 的提示,告诉它操作系统肯定会使用可用 RAM 来存储最近使用的文件。这样,您的查询优化器可能会决定访问磁盘数据并不像通常认为的那样昂贵。

于 2013-10-15T11:50:44.493 回答