Any issues with my tuning...

From: David Griffiths <dgriffiths(at)boats(dot)com>
To: pgsql-performance(at)postgresql(dot)org
Subject: Any issues with my tuning...
Date: 2003-10-13 19:43:32
Message-ID: 039801c391c2$4b83d600$6501a8c0@griffiths2
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-performance

I've been having performance issues with Postgres (sequential scans vs
index scans in an update statement). I've read that optimizer will
change it's plan based on the resources it thinks are available. In
addition, I've read alot of conflicting info on various parameters, so
I'd like to sort those out as well.

Here's the query I've been having problems with:

UPDATE user_account SET last_name='abc'
FROM commercial_entity ce, commercial_service cs
WHERE user_account.user_account_id = ce.user_account_id AND
ce.commercial_entity_id=cs.commercial_entity_id;

or

UPDATE user_account SET last_name = 'abc'
WHERE EXISTS (SELECT 1 FROM commercial_entity ce, commercial_service cs
WHERE user_account.user_account_id = ce.user_account_id AND
ce.commercial_entity_id = cs.commercial_entity_id);

Both are about the same.

All columns are indexed; all column-types are the same (numeric(10,0)).
A vacuum analyze was run just before the last attempt at running the
above statement.


MACHINE STATS
---------------------------
The machine is a dual-Pentium 3 933mhz, 2 gig of RAM, RAID 5 (3xWestern
Digital 80 gig drives with 8-meg buffers on 3Ware), Red Hat 9.0


POSTGRES TUNING INFO
---------------------------------------

Here are part of the contents of my sysctl.conf file (note that I've
played with values as low as 600000 with no difference)
kernel.shmmax=1400000000
kernel.shmall=1400000000

Here's the uncommented-lines from the postgresql.conf file (not the
default one in the /usr/local/pgsql directory - I've initialzed the
database on a different mount point with more space):

tcpip_socket = true
max_connections = 500
shared_buffers = 96000 # min max_connections*2 or 16, 8KB each
wal_buffers = 64 # min 4, typically 8KB each
sort_mem = 2048 # min 64, size in KB
effective_cache_size = 6000 # typically 8KB each
LC_MESSAGES = 'en_US.UTF-8'
LC_MONETARY = 'en_US.UTF-8'
LC_NUMERIC = 'en_US.UTF-8'
LC_TIME = 'en_US.UTF-8'

Note that I've played with all these values; shared_buffers has been as
low as 5000, and effective_cache_size has been as high as 50000. Sort
mem has varied between 1024 bytes and 4096 bytes. wal_buffers have been
between 16 and 128.


INFO FROM THE MACHINE
-----------------------------------------
Here are the vmstat numbers while running the query.

procs memory swap io system
cpu
r b w swpd free buff cache si so bi bo in cs us
sy id
0 1 2 261940 11624 110072 1334896 12 0 12 748 177 101
2 4 95
0 1 1 261940 11628 110124 1334836 0 0 0 1103 170 59
2 1 97
0 3 1 261928 11616 110180 1334808 3 0 6 1156 169 67
2 2 96
0 2 1 261892 11628 110212 1334636 7 0 7 1035 186 100
2 2 96
0 1 1 261796 11616 110272 1334688 18 0 18 932 169 79
2 1 97
0 1 1 261780 11560 110356 1334964 3 0 3 4155 192 118
2 7 92
0 1 1 261772 11620 110400 1334956 2 0 2 939 162 63
3 0 97
0 1 3 261744 11636 110440 1334872 6 0 9 1871 171 104
3 2 95
0 0 0 261744 13488 110472 1332244 0 0 0 922 195 1271
3 2 94
0 0 0 261744 13436 110492 1332244 0 0 0 24 115 47
0 1 99
0 0 0 261744 13436 110492 1332244 0 0 0 6 109 36
0 5 95
0 0 0 261744 13436 110492 1332244 0 0 0 6 123 63
0 0 100
0 0 0 261744 13436 110492 1332244 0 0 0 6 109 38
0 0 100
0 0 0 261744 13436 110492 1332244 0 0 0 6 112 39
0 1 99

I'm not overly familiar with Linux, but the swap in-out seems low, as
does the io in-out. Have I allocated too much memory? Regardless, it
doesn't explain why the optimizer would decide to do a sequential scan.

Here's the explain-analyze:

Merge Join (cost=11819.21..15258.55 rows=12007 width=752) (actual
time=4107.64..5587.81 rows=20880 loops=1)
Merge Cond: ("outer".commercial_entity_id =
"inner".commercial_entity_id)
-> Index Scan using comm_serv_comm_ent_id_i on commercial_service cs
(cost=0.00..3015.53 rows=88038 width=12) (actual time=0.05..487.23
rows=88038 loops=1)
-> Sort (cost=11819.21..11846.08 rows=10752 width=740) (actual
time=3509.07..3955.15 rows=25098 loops=1)
Sort Key: ce.commercial_entity_id
-> Merge Join (cost=0.00..9065.23 rows=10752 width=740)
(actual time=0.18..2762.13 rows=7990 loops=1)
Merge Cond: ("outer".user_account_id =
"inner".user_account_id)
-> Index Scan using user_account_pkey on user_account
(cost=0.00..8010.39 rows=72483 width=716) (actual time=0.05..2220.86
rows=72483 loops=1)
-> Index Scan using comm_ent_usr_acc_id_i on
commercial_entity ce (cost=0.00..4787.69 rows=78834 width=24) (actual
time=0.02..55.64 rows=7991 loops=1)
Total runtime: 226239.77 msec
(10 rows)

------------------------------------------------------------

Tied up in all this is my inability to grasp what shared_buffers do

From " http://www.varlena.com/varlena/GeneralBits/Tidbits/perf.html
<http://www.varlena.com/varlena/GeneralBits/Tidbits/perf.html> ":

"shbufShared buffers defines a block of memory that PostgreSQL will use
to hold requests that are awaiting attention from the kernel buffer and
CPU." and "The shared buffers parameter assumes that OS is going to
cache a lot of files and hence it is generally very low compared with
system RAM."

From " http://www.lyris.com/lm_help/6.0/tuning_postgresql.html
<http://www.lyris.com/lm_help/6.0/tuning_postgresql.html> "

"Increase the buffer size. Postgres uses a shared memory segment among
its subthreads to buffer data in memory. The default is 512k, which is
inadequate. On many of our installs, we've bumped it to ~16M, which is
still small. If you can spare enough memory to fit your whole database
in memory, do so."

Our database (in Oracle) is just over 4 gig in size; obviously, this
won't comfortably fit in memory (though we do have an Opteron machine
inbound for next week with 4-gig of RAM and SCSI hard-drives). The more
of it we can fit in memory the better.

What about changing these costs - the doc at
http://www.varlena.com/varlena/GeneralBits/Tidbits/annotated_conf_e.html
<http://www.varlena.com/varlena/GeneralBits/Tidbits/annotated_conf_e.htm
l> doesn't go into a lot of detail. I was thinking that maybe the
optimizer decided it was faster to do a sequential scan rather than an
index scan based on an analysis of the cost using these values.

#random_page_cost = 4 # units are one sequential page fetch
cost
#cpu_tuple_cost = 0.01 # (same)
#cpu_index_tuple_cost = 0.001 # (same)
#cpu_operator_cost = 0.0025 # (same)

David

Responses

Browse pgsql-performance by date

  From Date Subject
Next Message Ron Johnson 2003-10-13 20:53:04 Re: Any issues with my tuning...
Previous Message Sean Chittenden 2003-10-13 19:10:23 Re: go for a script! / ex: PostgreSQL vs. MySQL