Saya memiliki instance PostgreSQL 9.2 yang berjalan pada RHEL 6.3, mesin 8-core dengan 16GB RAM. Server didedikasikan untuk basis data ini. Mengingat postgresql.conf default cukup konservatif mengenai pengaturan memori, saya pikir mungkin ide yang baik untuk memungkinkan Postgres menggunakan lebih banyak memori. Yang mengejutkan saya, mengikuti saran di wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server secara signifikan melambat hampir setiap kueri yang saya jalankan tetapi jelas lebih terlihat pada kueri yang lebih kompleks.
Saya juga mencoba menjalankan pgtune yang memberikan rekomendasi berikut dengan lebih banyak parameter yang disetel, tetapi itu tidak mengubah apa pun. Ini menunjukkan shared_buffers dari 1/4 ukuran RAM yang tampaknya sejalan dengan saran di tempat lain (dan pada wiki PG khususnya).
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
Saya mencoba mengindeks ulang seluruh database setelah mengubah pengaturan (menggunakan reindex database
), tetapi itu tidak membantu. Saya bermain-main dengan shared_buffers dan work_mem. Mengubahnya secara bertahap dari nilai standar yang sangat konservatif (128k / 1MB) secara bertahap menurunkan kinerja.
Saya berlari EXPLAIN (ANALYZE,BUFFERS)
pada beberapa pertanyaan dan pelakunya tampaknya Hash Join secara signifikan lebih lambat. Tidak jelas bagi saya mengapa.
Untuk memberikan beberapa contoh spesifik, saya memiliki pertanyaan berikut. Ini berjalan dalam ~ 2100 ms pada konfigurasi default dan ~ 3300 ms pada konfigurasi dengan peningkatan ukuran buffer:
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)
untuk kueri di atas:
- Buffer default: http://explain.depesz.com/s/xaHJ
- Buffer yang lebih besar: http://explain.depesz.com/s/Plk
Pertanyaannya adalah mengapa saya mengamati penurunan kinerja ketika saya meningkatkan ukuran buffer? Mesin pasti tidak kehabisan memori. Alokasi jika memori bersama di OS adalah ( shmmax
dan shmall
) diatur ke nilai yang sangat besar, itu seharusnya tidak menjadi masalah. Saya juga tidak mendapatkan kesalahan dalam log Postgres. Saya menjalankan autovacuum dalam konfigurasi default, tetapi saya tidak berharap ada hubungannya dengan itu. Semua pertanyaan dijalankan pada mesin yang sama beberapa detik terpisah, hanya dengan konfigurasi yang diubah (dan restart PG).
Sunting: Saya baru saja menemukan satu fakta yang sangat menarik: ketika saya melakukan tes yang sama pada pertengahan 2010 iMac (OSX 10.7.5) saya juga dengan Postgres 9.2.1 dan 16GB RAM, saya tidak mengalami perlambatan. Secara khusus:
set work_mem='1MB';
select ...; // running time is ~1800 ms
set work_mem='96MB';
select ...' // running time is ~1500 ms
Ketika saya melakukan permintaan yang persis sama (yang di atas) dengan data yang persis sama di server saya mendapatkan 2100 ms dengan work_mem = 1MB dan 3200 ms dengan 96 MB.
Mac memiliki SSD sehingga bisa dimengerti lebih cepat, tetapi menunjukkan perilaku yang saya harapkan.
Lihat juga diskusi tindak lanjut tentang kinerja pgsql .