Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread Ivan Voras

On 08/07/2011 01:56, lars wrote:


Setup:
PostgreSQL 9.1beta2 on a high memory (~68gb, 12 cores) EC2 Linux
instance (kernel 2.6.35) with the database and
WAL residing on the same EBS volume with EXT4 (data=ordered, barriers=1)
- yes that is not an ideal setup
(WAL should be on separate drive, EBS is slow to begin, etc), but I am
mostly interested in read performance for a fully cached database.


I know you said you know these things - but do you really know the 
(huge) extent to which all your IO is slowed? Even context switches in a 
virtualized environment are slowed down by a huge margin - which would 
make practically all in-memory lock operations very slow - much slower 
than they would be on real hardware, and EBS by definition is even 
slower then regular private virtual storage environments. I regrettably 
didn't bookmark the page which did exact measurements of EBS, but 
http://www.google.com/search?q=how+slow+is+ec2 will illustrate my point. 
(of course, you may already know all this :) ).




--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread Merlin Moncure
On Tue, Jul 12, 2011 at 8:22 AM, Ivan Voras ivo...@freebsd.org wrote:
 On 08/07/2011 01:56, lars wrote:

 Setup:
 PostgreSQL 9.1beta2 on a high memory (~68gb, 12 cores) EC2 Linux
 instance (kernel 2.6.35) with the database and
 WAL residing on the same EBS volume with EXT4 (data=ordered, barriers=1)
 - yes that is not an ideal setup
 (WAL should be on separate drive, EBS is slow to begin, etc), but I am
 mostly interested in read performance for a fully cached database.

 I know you said you know these things - but do you really know the (huge)
 extent to which all your IO is slowed? Even context switches in a
 virtualized environment are slowed down by a huge margin - which would make
 practically all in-memory lock operations very slow - much slower than they
 would be on real hardware, and EBS by definition is even slower then
 regular private virtual storage environments. I regrettably didn't bookmark
 the page which did exact measurements of EBS, but
 http://www.google.com/search?q=how+slow+is+ec2 will illustrate my point. (of
 course, you may already know all this :) ).

sure, but the OP's question is valid: in postgres, readers don't block
writers, so why is the reader waiting?  I'd like to know definitively:
*) is the reader bottlenecked on disk i/o (it seems yes)
*) is that disk i/o heap or wal (it seems wal)
*) is that disk i/o reading/writing (it seems writing)
*) given the above, why is this happening (presumably disk page tidying)?

We need some more information here. I'd like to see the table
information -- at least the average width of the record both pre/post
update, if it is or is not toasted, and the number of size and indexes
pre/post update.  I'm really suspicious of the virtualization tech as
well -- is it possible to run this test on at least semi decent native
hardware?

merlin

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread Ivan Voras

On 12/07/2011 16:18, Merlin Moncure wrote:

On Tue, Jul 12, 2011 at 8:22 AM, Ivan Vorasivo...@freebsd.org  wrote:

On 08/07/2011 01:56, lars wrote:


Setup:
PostgreSQL 9.1beta2 on a high memory (~68gb, 12 cores) EC2 Linux
instance (kernel 2.6.35) with the database and
WAL residing on the same EBS volume with EXT4 (data=ordered, barriers=1)
- yes that is not an ideal setup
(WAL should be on separate drive, EBS is slow to begin, etc), but I am
mostly interested in read performance for a fully cached database.


I know you said you know these things - but do you really know the (huge)
extent to which all your IO is slowed? Even context switches in a
virtualized environment are slowed down by a huge margin - which would make
practically all in-memory lock operations very slow - much slower than they
would be on real hardware, and EBS by definition is even slower then
regular private virtual storage environments. I regrettably didn't bookmark
the page which did exact measurements of EBS, but
http://www.google.com/search?q=how+slow+is+ec2 will illustrate my point. (of
course, you may already know all this :) ).


sure, but the OP's question is valid: in postgres, readers don't block
writers, so why is the reader waiting?


Yes, but I'm suggesting a different question: are we sure we are not 
seeing the influences of the environment (EC2+EBS) instead of the 
software system?



We need some more information here.


Definitely.



--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread Ivan Voras

On 12/07/2011 02:09, lars wrote:


Oh, and iowait hovers around 20% when SELECTs are slow:

avg-cpu: %user %nice %system %iowait %steal %idle
1.54 0.00 0.98 18.49 0.07 78.92

When SELECTs are fast it looks like this:
avg-cpu: %user %nice %system %iowait %steal %idle
8.72 0.00 0.26 0.00 0.00 91.01

Note that this is a 12 core VM. So one core at 100% would show as 8.33%
CPU.


Now only if you could do an iostat -x and show the output in both cases...


--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] Memory usage of auto-vacuum

2011-07-12 Thread Gael Le Mignot
Hello,

Here is an update on my problem :

- the problem was caused by VACUUM ANALYZE, but by a plain VACUUM ;

- it was exactly the same with manual and automatic VACUUM ANALYZE ;

- it was caused by a GIN index on a tsvector, using a very high (1)
  statistics target.

Setting back the statistics to 1000  reduced the amount of RAM used to a
very reasonable amount.

The value of 1 is indeed  not very realistic, but I think that would
deserve some mention on the  documentation, if possible with an estimate
of  the maximal memory  usage for  a given  statistics target  and table
size.

Do  you think  it's a  good idea,  and if  so, if  that estimate  can be
reasonably made ?

Regards,

-- 
Gaël Le Mignot - g...@pilotsystems.net
Pilot Systems - 9, rue Desargues - 75011 Paris
Tel : +33 1 44 53 05 55 - www.pilotsystems.net
Gérez vos contacts et vos newsletters : www.cockpit-mailing.com

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread Merlin Moncure
On Tue, Jul 12, 2011 at 9:36 AM, Kevin Grittner
kevin.gritt...@wicourts.gov wrote:
 lars lhofha...@yahoo.com wrote:

 I am not trying to optimize this particular use case, but rather
 to understand what Postgres is doing, and why SELECT queries are
 affected negatively (sometimes severely) by concurrent (or even
 preceding) UPDATEs at all when the database resides in the cache
 completely.

 I think we're stuck in terms of trying to guess what is causing the
 behavior you are seeing.  Things which would help get it unstuck:

 (1)  More information about your load process.  Looking at the code,
 I could sort of see a possible path to this behavior if the load
 process involves any adjustments beyond straight INSERTs or COPYs
 in.

 (2)  You could poke around with a profiler, a debugger, and/or
 the contrib/pageinspect module to sort things out.


hm, also strace on the 'select' process might give some clues.

merlin

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


[PERFORM] Planner choosing NestedLoop, although it is slower...

2011-07-12 Thread Mario Splivalo

Hi, all.

I have a query, looking like this:
SELECT
pub_date
FROM
tubesite_object
INNER JOIN tubesite_image
ON tubesite_image.object_ptr_id = tubesite_object.id
WHERE
tubesite_object.site_id = 8
AND tubesite_object.pub_date  E'2011-07-12 13:25:00'
ORDER BY
tubesite_object.pub_date ASC
LIMIT 21;


That query takes cca 10-15 seconds to run. Here is query plan:

 Limit  (cost=0.00..415.91 rows=21 width=8) (actual 
time=11263.089..11263.089 rows=0 loops=1)
   -  Nested Loop  (cost=0.00..186249.55 rows=9404 width=8) (actual 
time=11263.087..11263.087 rows=0 loops=1)
 -  Index Scan using tubesite_object_pub_date_idx on 
tubesite_object  (cost=0.00..183007.09 rows=9404 width=12) (actual 
time=0.024..11059.487 rows=9374 loops=1)
   Index Cond: (pub_date  '2011-07-12 
13:25:00-05'::timestamp with time zone)

   Filter: (site_id = 8)
 -  Index Scan using tubesite_image_pkey on tubesite_image 
(cost=0.00..0.33 rows=1 width=4) (actual time=0.021..0.021 rows=0 
loops=9374)
   Index Cond: (tubesite_image.object_ptr_id = 
tubesite_object.id)

 Total runtime: 11263.141 ms


This query runs quickly (around second or two) when there is only few 
connections to the database. Once I have 50-80 connections (200 is the 
limit, although I never have more than 120-150 connections), that query 
takes around 10-15 seconds.


But, if I disable nestedloops, here is the query plan:

 Limit  (cost=22683.45..22683.51 rows=21 width=8) (actual 
time=136.009..136.009 rows=0 loops=1)
   -  Sort  (cost=22683.45..22706.96 rows=9404 width=8) (actual 
time=136.007..136.007 rows=0 loops=1)

 Sort Key: tubesite_object.pub_date
 Sort Method:  quicksort  Memory: 25kB
 -  Hash Join  (cost=946.51..22429.91 rows=9404 width=8) 
(actual time=135.934..135.934 rows=0 loops=1)
   Hash Cond: (tubesite_object.id = 
tubesite_image.object_ptr_id)
   -  Bitmap Heap Scan on tubesite_object 
(cost=545.40..21828.97 rows=9404 width=12) (actual time=20.874..104.075 
rows=9374 loops=1)

 Recheck Cond: (site_id = 8)
 Filter: (pub_date  '2011-07-12 
13:25:00-05'::timestamp with time zone)
 -  Bitmap Index Scan on tubesite_object_site_id 
(cost=0.00..543.05 rows=9404 width=0) (actual time=18.789..18.789 
rows=9374 loops=1)

   Index Cond: (site_id = 8)
   -  Hash  (cost=215.49..215.49 rows=14849 width=4) 
(actual time=21.068..21.068 rows=14849 loops=1)
 -  Seq Scan on tubesite_image  (cost=0.00..215.49 
rows=14849 width=4) (actual time=0.029..9.073 rows=14849 loops=1)

 Total runtime: 136.287 ms


Now, if I disable nested loops in postgres.conf, then my load average on 
the server goes skyhigh (i presume because a lot of other queries are 
now being planned incorrectly).


I have set up default_statistics_target to 2000, and have vacumed and 
analyzed the database.


Here are the other options I have set up in postgresql.conf (that differ 
from the default settings):


 version | PostgreSQL 8.4.8 on x86_64-pc-linux-gnu, 
compiled by GCC gcc-4.3.real (Debian 4.3.2-1.1) 4.3.2, 64-bit

 checkpoint_segments | 64
 default_statistics_target   | 2000
 effective_cache_size| 20GB
 external_pid_file   | /var/run/postgresql/8.4-main.pid
 lc_collate  | en_US.UTF-8
 lc_ctype| en_US.UTF-8
 listen_addresses| *
 log_autovacuum_min_duration | 0
 log_checkpoints | on
 log_line_prefix | %t [%p]: [%l-1]
 log_min_duration_statement  | 1s
 maintenance_work_mem| 256MB
 max_connections | 200
 max_stack_depth | 3MB
 port| 5432
 server_encoding | UTF8
 shared_buffers  | 2GB
 statement_timeout   | 30min
 temp_buffers| 4096
 TimeZone| localtime
 track_activity_query_size   | 2048
 unix_socket_directory   | /var/run/postgresql
 wal_buffers | 128MB
 work_mem| 64MB



Why is planner using NestedLoops, that is, what can I do to make him NOT 
to use NestedLoops (other than issuing SET enable_nestloop TO false; 
before each query) ?


Mario

--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread lars

On 07/12/2011 08:13 AM, Ivan Voras wrote:

On 12/07/2011 02:09, lars wrote:


Oh, and iowait hovers around 20% when SELECTs are slow:

avg-cpu: %user %nice %system %iowait %steal %idle
1.54 0.00 0.98 18.49 0.07 78.92

When SELECTs are fast it looks like this:
avg-cpu: %user %nice %system %iowait %steal %idle
8.72 0.00 0.26 0.00 0.00 91.01

Note that this is a 12 core VM. So one core at 100% would show as 8.33%
CPU.


Now only if you could do an iostat -x and show the output in both 
cases...




Sure (sorry for missing details):

iostat -x during selects when all's fine:
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
   8.250.000.000.000.00   91.75

Device: rrqm/s   wrqm/s r/s w/s   rsec/s   wsec/s 
avgrq-sz avgqu-sz   await  svctm  %util
xvdap10.00 1.000.002.00 0.0024.00
12.00 0.000.00   0.00   0.00
xvdf  0.00 0.000.000.00 0.00 0.00 
0.00 0.000.00   0.00   0.00
xvdg  0.00 0.000.000.00 0.00 0.00 
0.00 0.000.00   0.00   0.00


xvdap1 is OS volumn.
xvdf holds the database files
xvdg holds the WAL

No IO on database/WAL volumes, one core is pegged close to 100% CPU.



iostat -x during update:
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
   1.050.000.584.000.00   94.37

Device: rrqm/s   wrqm/s r/s w/s   rsec/s   wsec/s 
avgrq-sz avgqu-sz   await  svctm  %util
xvdap10.00 0.000.000.00 0.00 0.00 
0.00 0.000.00   0.00   0.00
xvdf  0.00 0.007.000.00   128.00 0.00
18.29 0.000.00   0.00   0.00
xvdg  0.00  7352.000.00  804.00 0.00 62368.00
77.5766.07   68.83   0.86  69.20


Just updating the WAL.

---

and while it's checkpointing:
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
   0.640.000.328.880.00   90.16

Device: rrqm/s   wrqm/s r/s w/s   rsec/s   wsec/s 
avgrq-sz avgqu-sz   await  svctm  %util
xvdap10.00 0.000.000.00 0.00 0.00 
0.00 0.000.00   0.00   0.00
xvdf  0.00  2548.002.00 1658.0032.00 33408.00
20.14   144.18   86.69   0.60 100.00
xvdg  0.00  5428.000.00  778.00 0.00 58480.00
75.1777.44  100.22   1.21  94.00


Updating the WAL, and database volume due to checkpointing.

--

iostat -x after I stopped the update process and checkpointing is done:
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
   0.000.000.000.000.00  100.00

Device: rrqm/s   wrqm/s r/s w/s   rsec/s   wsec/s 
avgrq-sz avgqu-sz   await  svctm  %util
xvdap10.00 0.000.000.00 0.00 0.00 
0.00 0.000.00   0.00   0.00
xvdf  0.00 0.000.000.00 0.00 0.00 
0.00 0.000.00   0.00   0.00
xvdg  0.00 0.000.000.00 0.00 0.00 
0.00 0.000.00   0.00   0.00


No activity at all.

-

iostat -x after I started the select queries after the updates:
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
   2.090.001.49   12.150.00   84.26

Device: rrqm/s   wrqm/s r/s w/s   rsec/s   wsec/s 
avgrq-sz avgqu-sz   await  svctm  %util
xvdap10.00 0.000.000.00 0.00 0.00 
0.00 0.000.00   0.00   0.00
xvdf  0.00 8.000.002.00 0.0080.00
40.00 0.002.00   2.00   0.40
xvdg  0.00  7844.001.00 1098.00 8.00 82336.00
74.9358.27   59.39   0.70  77.20


Heavy writes to the WAL volume.

select * from pg_stat_activity;
 datid | datname | procpid | usesysid | usename  | application_name | 
client_addr | client_hostname | client_port | 
backend_start |  xact_start   |  qu

ery_start  | waiting | current_query
---+-+-+--+--+--+-+-+-+---+---+
---+-+---
 16385 | lars|2654 |16384 | lars |  | 
127.0.0.1   | |   44972 | 2011-07-12 
18:44:09.479581+00 | 2011-07-12 18:50:32.629412+00 | 2011-07-12
18:50:32.629473+00 | f   | select count(*) from test where tenant = 
$1 and created_date = $2
 16385 | lars|2658 |   10 | postgres | psql 
| | |  -1 | 2011-07-12 
18:49:02.675436+00 | 2011-07-12 18:50:32.631013+00 | 2011-07-12

18:50:32.631013+00 | 

Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread Kevin Grittner
lars lhofha...@yahoo.com wrote:
 
 select count(*) from test where tenant = $1 and created_date = $2
 
Ah, that might be a major clue -- prepared statements.
 
What sort of a plan do you get for that as a prepared statement? 
(Note, it is very likely *not* to be the same plan as you get if you
run with literal values!)  It is not at all unlikely that it could
resort to a table scan if you have one tenant which is five or ten
percent of the table, which would likely trigger the pruning as it
passed over the modified pages.
 
-Kevin

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread Kevin Grittner
lars lhofha...@yahoo.com wrote:
 
 select count(*) from test where tenant = $1 and created_date = $2
 
Thinking about this some more, it would be interesting to know your
PostgreSQL configuration.  I seem to remember you mentioning some
settings up-thread, but I'm not sure whether it was comprehensive. 
Could you paste the result of running the query on this Wiki page?:
 
http://wiki.postgresql.org/wiki/Server_Configuration
 
It might be that if you generate your queries with literals rather
than using server-side prepared statements, and tweak a couple
configuration settings, this problem will evaporate.
 
-Kevin

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] Planner choosing NestedLoop, although it is slower...

2011-07-12 Thread Tom Lane
Mario Splivalo mario.spliv...@megafon.hr writes:
   Limit  (cost=0.00..415.91 rows=21 width=8) (actual 
 time=11263.089..11263.089 rows=0 loops=1)
 -  Nested Loop  (cost=0.00..186249.55 rows=9404 width=8) (actual 
 time=11263.087..11263.087 rows=0 loops=1)

 Why is planner using NestedLoops,

Because it thinks the LIMIT will kick in and end the query when the join
is only 21/9404ths (ie, a fraction of a percent) complete.  A NestLoop
results in saving a lot of work in that situation, whereas hash-and-sort
has to do the whole join despite the LIMIT.

What you need to look into is why the estimated join size is 9400 rows
when the actual join size is zero.  Are both tables ANALYZEd?  Are you
intentionally selecting rows that have no join partners?

regards, tom lane

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread lars

On 07/12/2011 12:08 PM, Kevin Grittner wrote:

larslhofha...@yahoo.com  wrote:


select count(*) from test where tenant = $1 and created_date = $2


Ah, that might be a major clue -- prepared statements.

What sort of a plan do you get for that as a prepared statement?
(Note, it is very likely *not* to be the same plan as you get if you
run with literal values!)  It is not at all unlikely that it could
resort to a table scan if you have one tenant which is five or ten
percent of the table, which would likely trigger the pruning as it
passed over the modified pages.

-Kevin
So a read of a row *will* trigger dead tuple pruning, and that requires 
WAL logging, and this is known/expected?
This is actually the only answer I am looking for. :) I have not seen 
this documented anywhere.


I know that Postgres will generate general plans for prepared statements 
(how could it do otherwise?),

I also know that it sometimes chooses a sequential scan.
This can always be tweaked to touch fewer rows and/or use a different 
plan. That's not my objective, though!


The fact that a select (maybe a big analytical query we'll run) touching 
many rows will update the WAL and wait
(apparently) for that IO to complete is making a fully cached database 
far less useful.

I just artificially created this scenario.

... Just dropped the table to test something so I can't get the plan 
right now. Will send an update as soon as I get

it setup again.

Thanks again.

-- Lars


--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread Kevin Grittner
lars lhofha...@yahoo.com wrote:
 
 So a read of a row *will* trigger dead tuple pruning, and that
 requires WAL logging, and this is known/expected?
 
Yes, because pruning dead line pointers will make subsequent reads
faster.  It's intended to be an optimization.
 
 This is actually the only answer I am looking for. :) I have not
 seen this documented anywhere.
 
You would currently need to look at the README-HOT file or source
code, I think.  There probably should be some mention in the user
docs, but I haven't noticed any, and it is more technical than most
of the documentation gets.  Perhaps a note block somewhere...
 
 The fact that a select (maybe a big analytical query we'll run)
 touching many rows will update the WAL and wait (apparently) for
 that IO to complete is making a fully cached database far less
 useful.
 
Well, I've never run into this because I have directly attached
storage through a RAID controller with a battery-backed cache
configured for write-back.  The pruning is pretty light on CPU
usage, and with a BBU controller, the WAL writes just move from one
cache to another.
 
If that's not an option for you, you could contrive to have the
update code reread the modified rows after COMMIT, or configure your
autovacuum to be very aggressive so that a background process
usually takes care of this before a SELECT gets to it.  And there's
a good chance that tuning your query and/or running with literal
values available to the planner would be a big net win even without
this issue; if this issue is a problem for you, it's just another
reason to do that tuning.
 
 Just dropped the table to test something so I can't get the plan 
 right now. Will send an update as soon as I get
 it setup again.
 
I'll be surprised if you don't see a seqscan.  The most interesting
bit at this point (at least to me) is working on tuning the cost
factors for the planner.
 
-Kevin

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread lars

On 07/12/2011 01:04 PM, lars wrote:

On 07/12/2011 12:08 PM, Kevin Grittner wrote:

larslhofha...@yahoo.com  wrote:


select count(*) from test where tenant = $1 and created_date = $2


Ah, that might be a major clue -- prepared statements.

What sort of a plan do you get for that as a prepared statement?
(Note, it is very likely *not* to be the same plan as you get if you
run with literal values!)  It is not at all unlikely that it could
resort to a table scan if you have one tenant which is five or ten
percent of the table, which would likely trigger the pruning as it
passed over the modified pages.

-Kevin
So a read of a row *will* trigger dead tuple pruning, and that 
requires WAL logging, and this is known/expected?
This is actually the only answer I am looking for. :) I have not seen 
this documented anywhere.


I know that Postgres will generate general plans for prepared 
statements (how could it do otherwise?),

I also know that it sometimes chooses a sequential scan.
This can always be tweaked to touch fewer rows and/or use a different 
plan. That's not my objective, though!


The fact that a select (maybe a big analytical query we'll run) 
touching many rows will update the WAL and wait
(apparently) for that IO to complete is making a fully cached database 
far less useful.

I just artificially created this scenario.

... Just dropped the table to test something so I can't get the plan 
right now. Will send an update as soon as I get

it setup again.

Thanks again.

-- Lars



Ok... Slightly changes the indexes:
\d test
Table lars.test
Column| Type  | Modifiers
--+---+---
 tenant   | character(15) |
 created_by   | character(15) |
 created_date | date  |
Indexes:
i1 btree (tenant)

So just just a simple index on tenant.

prepare x as select count(*) from test where tenant = $1 and 
created_date = $2;

PREPARE
explain execute x('001','2011-6-30');
  QUERY PLAN
---
 Aggregate  (cost=263301.40..263301.41 rows=1 width=0)
   -  Bitmap Heap Scan on test  (cost=3895.99..263299.28 rows=847 width=0)
 Recheck Cond: (tenant = $1)
 Filter: (created_date = $2)
 -  Bitmap Index Scan on i1  (cost=0.00..3895.77 rows=169372 
width=0)

   Index Cond: (tenant = $1)
(6 rows)

-- this is when the WAL rows are written:
explain (analyze on, buffers on) execute x('001','2011-6-30');
 QUERY PLAN

 Aggregate  (cost=263301.40..263301.41 rows=1 width=0) (actual 
time=191.150..191.151 rows=1 loops=1)

   Buffers: shared hit=3716
   -  Bitmap Heap Scan on test  (cost=3895.99..263299.28 rows=847 
width=0) (actual time=1.966..188.221 rows=3712 loops=1)

 Recheck Cond: (tenant = $1)
 Filter: (created_date = $2)
 Buffers: shared hit=3716
 -  Bitmap Index Scan on i1  (cost=0.00..3895.77 rows=169372 
width=0) (actual time=1.265..1.265 rows=3712 loops=1)

   Index Cond: (tenant = $1)
   Buffers: shared hit=20
 Total runtime: 191.243 ms
(10 rows)

-- this is when no WAL is written:
explain (analyze on, buffers on) execute x('001','2011-6-30');
 QUERY PLAN

 Aggregate  (cost=263301.40..263301.41 rows=1 width=0) (actual 
time=11.529..11.530 rows=1 loops=1)

   Buffers: shared hit=3715
   -  Bitmap Heap Scan on test  (cost=3895.99..263299.28 rows=847 
width=0) (actual time=1.341..9.187 rows=3712 loops=1)

 Recheck Cond: (tenant = $1)
 Filter: (created_date = $2)
 Buffers: shared hit=3715
 -  Bitmap Index Scan on i1  (cost=0.00..3895.77 rows=169372 
width=0) (actual time=0.756..0.756 rows=3712 loops=1)

   Index Cond: (tenant = $1)
   Buffers: shared hit=19
 Total runtime: 11.580 ms
(10 rows)

If you wanted to recreate this scenario I created a simple script to 
create the table:


create table test(tenant char(15), created_by char(15), created_date date);
insert into test values('x', 'y','2011-6-30');
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert 

Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread Merlin Moncure
On Tue, Jul 12, 2011 at 2:08 PM, Kevin Grittner
kevin.gritt...@wicourts.gov wrote:
 lars lhofha...@yahoo.com wrote:

 select count(*) from test where tenant = $1 and created_date = $2

 Ah, that might be a major clue -- prepared statements.

I'm really skeptical that this is the case -- the table is 100m and
there is no way you are banging through 100m in 500ms records
particularly if doing i/o.

Also regarding the page cleanup, IIRC the optimization only takes
place if the dead tuples are HOT -- when the OP opened the thread he
stated it was happening with update on indexed field (and later tested
it on unindexed field).

Something is not adding up here.  Perhaps there is an alternate route
to WAL logged activity from selects I'm not thinking of.  Right now
I'm thinking to run the selects on table 'a' and the inserts
concurrently on table 'b' and seeing how that behaves.  Another way to
get to the bottom is to oprofile the selecting-during-load backend to
see where the time is getting spent.   Alternative way to do this is
to strace attach to the selecting-during-load backend to see if it's
really writing to the WAL (I'm really curious about this).

Another interesting test would be to try and reproduce the results on
native machine. It should be possible to do this on your workstation
with a more modestly sized scaling factor.

merlin

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread Kevin Grittner
lars lhofha...@yahoo.com wrote:

 vacuum analyze;

I tried this out on a 16 core, 64 GB machine.  It was a replication
target for a few dozen source databases into a couple 2 TB reporting
databases, and had some light testing going on, but it was only at
about 50% capacity, so that shouldn't throw this off by *too* much,
I hope.  Since our data is long-lived enough to worry about
transaction ID freezing issues, I always follow a bulk load with
VACUUM FREEZE ANALYZE; so I did that here.  I also just threw this
into the 2 TB database without changing our configuration.  Among
other things, that means that autovacuum was on.

 prepare x as select count(*) from test where tenant = $1 and
 created_date = $2;
 prepare y as update test set created_by = $1 where tenant = $2 and
 created_date = $3;

 execute y('001', '001','2011-6-30');
 execute x('001','2011-6-30');

I ran x a bunch of times to get a baseline, then y once, then x a
bunch more times.  The results were a bit surprising:

cir= \timing
Timing is on.
cir= execute x('001','2011-6-30');
 count
---
  3456
(1 row)

Time: 9.823 ms
cir= execute x('001','2011-6-30');
 count
---
  3456
(1 row)

Time: 8.481 ms
cir= execute x('001','2011-6-30');
 count
---
  3456
(1 row)

Time: 14.054 ms
cir= execute x('001','2011-6-30');
 count
---
  3456
(1 row)

Time: 10.169 ms
cir= execute y('001', '001','2011-6-30');
UPDATE 3456
Time: 404.244 ms
cir= execute x('001','2011-6-30');
 count
---
  3456
(1 row)

Time: 128.643 ms
cir= execute x('001','2011-6-30');
 count
---
  3456
(1 row)

Time: 2.657 ms
cir= execute x('001','2011-6-30');
 count
---
  3456
(1 row)

Time: 5.883 ms
cir= execute x('001','2011-6-30');
 count
---
  3456
(1 row)

Time: 2.645 ms
cir= execute x('001','2011-6-30');
 count
---
  3456
(1 row)

Time: 2.753 ms
cir= execute x('001','2011-6-30');
 count
---
  3456
(1 row)

Time: 2.253 ms

Running the update made the next SELECT slow, then it was much
*faster*.  My best guess is that the data landed in a more
concentrated set of pages after the update, and once autovacuum
kicked in and cleaned things up it was able to get to that set of
data faster.

 On the face of it, though, this looks like Postgres would not be
 that useful as database that resides (mostly) in the cache.

   autovacuum   | off

Well, certainly not while under modification without running
autovacuum.  That's disabling an integral part of what keeps
performance up.  There are very few, if any, situations where
running PostgreSQL in production without autovacuum makes any sense,
and benchmarks which disable it don't give a very accurate picture
of typical performance.  Now, if you're looking to artificially
create a worst-case scenario, then it makes sense, but I'm not clear
on the point of it.

I do understand the impulse, though.  When we first started using
PostgreSQL there were certain very small tables which were updated
very frequently which got slow when autovacuum kicked in.  We made
autovacuum less aggressive, and found that things go worse!  Se we
went the other way and made autovacuum much more aggressive than the
defaults, and everything was fine.

-Kevin

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] Planner choosing NestedLoop, although it is slower...

2011-07-12 Thread Mario Splivalo

On 07/12/2011 10:04 PM, Tom Lane wrote:

Mario Splivalomario.spliv...@megafon.hr  writes:

   Limit  (cost=0.00..415.91 rows=21 width=8) (actual
time=11263.089..11263.089 rows=0 loops=1)
 -   Nested Loop  (cost=0.00..186249.55 rows=9404 width=8) (actual
time=11263.087..11263.087 rows=0 loops=1)



Why is planner using NestedLoops,


Because it thinks the LIMIT will kick in and end the query when the join
is only 21/9404ths (ie, a fraction of a percent) complete.  A NestLoop
results in saving a lot of work in that situation, whereas hash-and-sort
has to do the whole join despite the LIMIT.

What you need to look into is why the estimated join size is 9400 rows
when the actual join size is zero.  Are both tables ANALYZEd?  Are you
intentionally selecting rows that have no join partners?


Hi, Tom.

Yes, both tables have been ANALYZEd. What do you mean, intentilnaly 
selecting rows taht have no join partners?


Mario

--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread lars

On 07/12/2011 02:51 PM, Kevin Grittner wrote:

I ran x a bunch of times to get a baseline, then y once, then x a
bunch more times.  The results were a bit surprising:

cir=  \timing
Timing is on.
cir=  execute x('001','2011-6-30');
  count
---
   3456
(1 row)

Time: 9.823 ms
cir=  execute x('001','2011-6-30');
  count
---
   3456
(1 row)

Time: 8.481 ms
cir=  execute x('001','2011-6-30');
  count
---
   3456
(1 row)

Time: 14.054 ms
cir=  execute x('001','2011-6-30');
  count
---
   3456
(1 row)

Time: 10.169 ms
cir=  execute y('001', '001','2011-6-30');
UPDATE 3456
Time: 404.244 ms
cir=  execute x('001','2011-6-30');
  count
---
   3456
(1 row)

Time: 128.643 ms
cir=  execute x('001','2011-6-30');
  count
---
   3456
(1 row)

Time: 2.657 ms
cir=  execute x('001','2011-6-30');
  count
---
   3456
(1 row)

Time: 5.883 ms
cir=  execute x('001','2011-6-30');
  count
---
   3456
(1 row)

Time: 2.645 ms
cir=  execute x('001','2011-6-30');
  count
---
   3456
(1 row)

Time: 2.753 ms
cir=  execute x('001','2011-6-30');
  count
---
   3456
(1 row)

Time: 2.253 ms

Interesting. When you did you test, did you also find WAL write activity 
when running x the first time after y?

(It's very hard to catch in only a single query, though).


Running the update made the next SELECT slow, then it was much
*faster*.  My best guess is that the data landed in a more
concentrated set of pages after the update, and once autovacuum
kicked in and cleaned things up it was able to get to that set of
data faster.


   autovacuum   | off

Well, certainly not while under modification without running
autovacuum.  That's disabling an integral part of what keeps
performance up.
Oh, it's just switched off for testing, so that I can control when 
vacuum runs and make sure that it's not

skewing the results while I am measuring something.
In a real database I would probably err on vacuuming more than less.

For a fully cached database I would probably want to switch off HOT 
pruning and compaction (which from what we see
is done synchronously with the select) and leave it up to the 
asynchronous auto vacuum to do that. But maybe I am

still not quite understanding the performance implications.


--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] Planner choosing NestedLoop, although it is slower...

2011-07-12 Thread Tom Lane
Mario Splivalo mario.spliv...@megafon.hr writes:
 On 07/12/2011 10:04 PM, Tom Lane wrote:
 What you need to look into is why the estimated join size is 9400 rows
 when the actual join size is zero.  Are both tables ANALYZEd?  Are you
 intentionally selecting rows that have no join partners?

 Yes, both tables have been ANALYZEd. What do you mean, intentilnaly 
 selecting rows taht have no join partners?

I'm wondering why the actual join size is zero.  That seems like a
rather unexpected case for a query like this.

regards, tom lane

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread lars

On 07/12/2011 02:38 PM, Merlin Moncure wrote:


Something is not adding up here.  Perhaps there is an alternate route
to WAL logged activity from selects I'm not thinking of.  Right now
I'm thinking to run the selects on table 'a' and the inserts
concurrently on table 'b' and seeing how that behaves.  Another way to
get to the bottom is to oprofile the selecting-during-load backend to
see where the time is getting spent.   Alternative way to do this is
to strace attach to the selecting-during-load backend to see if it's
really writing to the WAL (I'm really curious about this).

Another interesting test would be to try and reproduce the results on
native machine. It should be possible to do this on your workstation
with a more modestly sized scaling factor.

merlin


Just tried with two of my test tables.
Updates on 'a' have no (measurable) effect on select from 'b'.

Back to the first case, here's an strace from the backend doing the 
select right after the updates.


Q\0\0\0`select count(*) from test1 ..., 8192, 0, NULL, NULL) = 97
gettimeofday({1310512219, 723762}, NULL) = 0
open(base/16385/33032, O_RDWR)= 8
lseek(8, 0, SEEK_END)   = 1073741824
open(base/16385/33032.1, O_RDWR|O_CREAT, 0600) = 9
lseek(9, 0, SEEK_END)   = 1073741824
open(base/16385/33032.2, O_RDWR|O_CREAT, 0600) = 10
lseek(10, 0, SEEK_END)  = 191348736
open(base/16385/33035, O_RDWR)= 11
lseek(11, 0, SEEK_END)  = 1073741824
open(base/16385/33035.1, O_RDWR|O_CREAT, 0600) = 12
lseek(12, 0, SEEK_END)  = 3571712
lseek(10, 0, SEEK_END)  = 191348736
brk(0x28ad000)  = 0x28ad000
mmap(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 
0) = 0x7f5f28ca
mmap(NULL, 266240, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 
0) = 0x7f5f28c5f000

munmap(0x7f5f28c5f000, 266240)  = 0
munmap(0x7f5f28ca, 135168)  = 0
open(pg_xlog/000100BB0012, O_RDWR) = 13
lseek(13, 1564672, SEEK_SET)= 1564672
write(13, 
f\320\1\0\1\0\0\0\273\0\0\0\0\340\27\22`\32\0\0002833!000..., 
2400256) = 2400256

fdatasync(13)   = 0
semop(229383, {{9, 1, 0}}, 1)   = 0
gettimeofday({1310512219, 885287}, NULL) = 0
sendto(5, 
\2\0\0\0\300\3\0\0\1@\0\0\t\0\0\0\1\0\0\0\0\0\0\0\353\4\0\0@\0\2\0..., 
960, 0, NULL, 0) = 960
sendto(5, 
\2\0\0\0\300\3\0\0\1@\0\0\t\0\0\0\0\0\0\0\0\0\0\0009\n\0\0@\0\2\0..., 
960, 0, NULL, 0) = 960
sendto(5, 
\2\0\0\0\300\3\0\0\1@\0\0\t\0\0\0\0\0\0\0\0\0\0\0v\n\0\0@\0\2\0..., 
960, 0, NULL, 0) = 960
sendto(5, 
\2\0\0\0\270\1\0\0\0\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\275\4\0\0\377\177\0\0..., 
440, 0, NULL, 0) = 440
sendto(6, 
T\0\0\0\36\0\1count\0\0\0\0\0\0\0\0\0\0\24\0\10\377\377\377\377\0\0D..., 
66, 0, NULL, 0) = 66


So the backend definitely writing to the WAL, directly and synchronously.

Selecting the same set of rows again:
Q\0\0\0`select count(*) from test1 ..., 8192, 0, NULL, NULL) = 97
gettimeofday({1310512344, 823728}, NULL) = 0
lseek(10, 0, SEEK_END)  = 191348736
lseek(12, 0, SEEK_END)  = 3571712
lseek(10, 0, SEEK_END)  = 191348736
brk(0x28d5000)  = 0x28d5000
brk(0x2915000)  = 0x2915000
brk(0x2897000)  = 0x2897000
gettimeofday({1310512344, 831043}, NULL) = 0
sendto(5, 
\2\0\0\0\350\0\0\0\1@\0\0\2\0\0\0\1\0\0\0\0\0\0\0\10\201\0\0?\0\2\0..., 232, 
0, NULL, 0) = 232
sendto(6, 
T\0\0\0\36\0\1count\0\0\0\0\0\0\0\0\0\0\24\0\10\377\377\377\377\0\0D..., 
66, 0, NULL, 0) = 66


No writing to the WAL.

-- Lars


--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] Planner choosing NestedLoop, although it is slower...

2011-07-12 Thread Mario Splivalo

On 07/13/2011 12:39 AM, Tom Lane wrote:

Mario Splivalomario.spliv...@megafon.hr  writes:

On 07/12/2011 10:04 PM, Tom Lane wrote:

What you need to look into is why the estimated join size is 9400 rows
when the actual join size is zero.  Are both tables ANALYZEd?  Are you
intentionally selecting rows that have no join partners?



Yes, both tables have been ANALYZEd. What do you mean, intentilnaly
selecting rows taht have no join partners?


I'm wondering why the actual join size is zero.  That seems like a
rather unexpected case for a query like this.


It is true that this particular query returns 0 rows. But it's created 
by django, and I can't do much to alter it.


Mario

--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] Planner choosing NestedLoop, although it is slower...

2011-07-12 Thread Mario Splivalo

On 07/13/2011 12:39 AM, Tom Lane wrote:

Mario Splivalomario.spliv...@megafon.hr  writes:

On 07/12/2011 10:04 PM, Tom Lane wrote:

What you need to look into is why the estimated join size is 9400 rows
when the actual join size is zero.  Are both tables ANALYZEd?  Are you
intentionally selecting rows that have no join partners?



Yes, both tables have been ANALYZEd. What do you mean, intentilnaly
selecting rows taht have no join partners?


I'm wondering why the actual join size is zero.  That seems like a
rather unexpected case for a query like this.


Yes, seems that planer gets confused by LIMIT. This query:

select * from tubesite_object join tubesite_image on id=object_ptr_id 
where site_id = 8 and pub_date  '2011-07-12 13:25:00' order by pub_date 
desc ;


Does not choose Nested Loop, and is done instantly (20 ms), and returns 
no rows. However, if I add LIMIT at the end, it chooses NestedLoop and 
it takes 500ms if I'm alone on the server, and 10+ seconds if there 50+ 
connections on the server.


Mario

--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread Tom Lane
Jeff Janes jeff.ja...@gmail.com writes:
 On 7/12/11, lars lhofha...@yahoo.com wrote:
 The fact that a select (maybe a big analytical query we'll run) touching
 many rows will update the WAL and wait
 (apparently) for that IO to complete is making a fully cached database
 far less useful.
 I just artificially created this scenario.

 I can't think of any reason that that WAL would have to be flushed
 synchronously.

Maybe he's running low on shared_buffers?  We would have to flush WAL
before writing a dirty buffer out, so maybe excessive pressure on
available buffers is part of the issue here.

regards, tom lane

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] Planner choosing NestedLoop, although it is slower...

2011-07-12 Thread Mario Splivalo

On 07/13/2011 02:53 AM, Mario Splivalo wrote:

On 07/13/2011 12:39 AM, Tom Lane wrote:

Mario Splivalomario.spliv...@megafon.hr writes:

On 07/12/2011 10:04 PM, Tom Lane wrote:

What you need to look into is why the estimated join size is 9400 rows
when the actual join size is zero. Are both tables ANALYZEd? Are you
intentionally selecting rows that have no join partners?



Yes, both tables have been ANALYZEd. What do you mean, intentilnaly
selecting rows taht have no join partners?


I'm wondering why the actual join size is zero. That seems like a
rather unexpected case for a query like this.


Yes, seems that planer gets confused by LIMIT. This query:

select * from tubesite_object join tubesite_image on id=object_ptr_id
where site_id = 8 and pub_date  '2011-07-12 13:25:00' order by pub_date
desc ;

Does not choose Nested Loop, and is done instantly (20 ms), and returns
no rows. However, if I add LIMIT at the end, it chooses NestedLoop and
it takes 500ms if I'm alone on the server, and 10+ seconds if there 50+
connections on the server.


As explained/suggested by RhodiumToad on IRC, adding composite index on 
(site_id, pub_date) made nestedloop query finish in around 100 seconds!


Thank you!

Mario

--
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


Re: [PERFORM] UPDATEDs slowing SELECTs in a fully cached database

2011-07-12 Thread Lars
shared_buffers is big enough to hold the entire database, and there is plenty 
of extra space. (verified with PG_buffercache) 
So i don't think that is the reason. 


Tom Lane t...@sss.pgh.pa.us schrieb:

Jeff Janes jeff.ja...@gmail.com writes:
 On 7/12/11, lars lhofha...@yahoo.com wrote:
 The fact that a select (maybe a big analytical query we'll run) touching
 many rows will update the WAL and wait
 (apparently) for that IO to complete is making a fully cached database
 far less useful.
 I just artificially created this scenario.

 I can't think of any reason that that WAL would have to be flushed
 synchronously.

Maybe he's running low on shared_buffers?  We would have to flush WAL
before writing a dirty buffer out, so maybe excessive pressure on
available buffers is part of the issue here.

   regards, tom lane

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance

-- 
Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance