我有一个运行在具有16GB RAM的8核RHEL 6.3计算机上的PostgreSQL 9.2实例。服务器专用于此数据库。鉴于默认的postgresql.conf在内存设置方面相当保守,我认为允许Postgres使用更多内存可能是一个好主意。令我惊讶的是,遵循wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server上的建议,实际上使我运行的每个查询速度显着降低,但是在更复杂的查询上显然更明显。
我还尝试运行pgtune,它给出了以下建议,并带有更多已调整的参数,但没有任何改变。它建议使用RAM大小的1/4的shared_buffers,这似乎与其他地方(尤其是PG Wiki)上的建议相符。
default_statistics_target = 50
maintenance_work_mem = 960MB
constraint_exclusion = on
checkpoint_completion_target = 0.9
effective_cache_size = 11GB
work_mem = 96MB
wal_buffers = 8MB
checkpoint_segments = 16
shared_buffers = 3840MB
max_connections = 80
我尝试在更改设置(使用reindex database
)后为整个数据库重新编制索引,但这也无济于事。我玩过shared_buffers和work_mem。从非常保守的默认值(128k / 1MB)逐渐更改它们会逐渐降低性能。
我遇到EXPLAIN (ANALYZE,BUFFERS)
了一些疑问,罪魁祸首似乎是哈希联接的速度明显慢。我不清楚为什么。
举一些具体的例子,我有以下查询。在默认配置下,它在〜2100ms内运行,在配置增加缓冲区的情况下,在〜3300ms内运行:
select count(*) from contest c
left outer join contestparticipant cp on c.id=cp.contestId
left outer join teammember tm on tm.contestparticipantid=cp.id
left outer join staffmember sm on cp.id=sm.contestparticipantid
left outer join person p on p.id=cp.personid
left outer join personinfo pi on pi.id=cp.personinfoid
where pi.lastname like '%b%' or pi.firstname like '%a%';
EXPLAIN (ANALYZE,BUFFERS)
对于上面的查询:
- 默认缓冲区:http://explain.depesz.com/s/xaHJ
- 更大的缓冲区:http://explain.depesz.com/s/Plk
问题是,为什么增加缓冲区大小时会观察到性能下降?机器肯定没有内存不足。如果将OS中的共享内存(shmmax
和shmall
)设置为非常大的值,那应该没有问题。我在Postgres日志中也没有收到任何错误。我在默认配置下运行autovacuum,但我不希望这与它有任何关系。所有查询都在相隔几秒钟的同一台计算机上运行,只是配置有所更改(并重新启动了PG)。
编辑:我发现一个特别有趣的事实:当我在2010年中的iMac(OSX 10.7.5)上也使用Postgres 9.2.1和16GB RAM进行相同的测试时,我没有遇到速度变慢的情况。特别:
set work_mem='1MB';
select ...; // running time is ~1800 ms
set work_mem='96MB';
select ...' // running time is ~1500 ms
当我对服务器上的数据进行完全相同的查询(上述查询)时,work_mem = 1MB时为2100毫秒,而96 MB时为3200毫秒。
Mac具有SSD,因此可以理解得更快,但是却表现出我所期望的行为。
另请参阅有关pgsql-performance的后续讨论。