[PERFORM] what does "initplan" operation in explain output mean?

2010-07-31 Thread Mark Rostron

We are running 8.3.10 64bit.

This message is a request for information about the "initplan" operation in 
explain plan.
I want to know if I can take advantage of it, and use it to initialize 
query-bounds for the purpose of enforcing constraint exclusion on a table which 
has been range-partitioned on a serial-id column.

Compare the plans below.

They all do the same thing and delete from a table named work_active (about 
500rows), which is a subset of work_unit (about 50m rows).

Stmt_3 is the plan currently in use.

Stmt_4 and stmt_5 ilustrate explain plans of two variants of stmt_3 (no 
partitions yet):

-  Limit the sub-query using constants (derived from a prior query  
min() and max() against work_active), (ref stmt_4 below) or

-  Try and do something cute and do a subquery using min() and max() 
(ref stmt_5 below).


My questions are:

-  What does the "initplan" operation do? ( I can take a guess, but 
could someone give me some details, cos the docn about it is pretty sparse).

-  Will this enable constraint exclusion on the work_unit table if we 
introduce partitioning?



Thanks in adv for any help you can give me.
Mr







caesius=# \i stmt_3.sql
explain
DELETE FROM work_active wa
WHERE EXISTS (
 SELECT 1
 FROM   work_unit wu
  , run r
 WHERE  wu.id = wa.wu_id
 ANDwu.run_id = r.id
 AND(( (wu.status not in (2,3)) OR (wu.stop_time is not null)) OR 
(r.status > 2) )
 LIMIT 1
);
   QUERY PLAN

Seq Scan on work_active wa  (cost=0.00..23078.82 rows=370 width=6)
   Filter: (subplan)
   SubPlan
 ->  Limit  (cost=0.00..30.53 rows=1 width=0)
   ->  Nested Loop  (cost=0.00..30.53 rows=1 width=0)
 Join Filter: ((wu.status <> ALL ('{2,3}'::integer[])) OR 
(wu.stop_time IS NOT NULL) OR (r.status > 2))
 ->  Index Scan using tmp_work_unit_pkey on work_unit wu  
(cost=0.00..19.61 rows=1 width=16)
   Index Cond: (id = $0)
 ->  Index Scan using run_pkey on run r  (cost=0.00..10.91 
rows=1 width=8)
   Index Cond: (r.id = wu.run_id)
(10 rows)





caesius=# \i stmt_4.sql
explain
DELETE FROM work_active wa
where exists (
 SELECT 1
 FROM   work_unit wu
  , run r
 WHERE  wu.id = wa.wu_id

 ANDwu.id between 100 and 110
 ANDwu.run_id = r.id
 AND(( (wu.status not in(2,3) ) OR (wu.stop_time is not null)) OR 
(r.status > 2) )
 LIMIT 1
);
   QUERY PLAN

Seq Scan on work_active wa  (cost=0.00..22624.37 rows=362 width=6)
   Filter: (subplan)
   SubPlan
 ->  Limit  (cost=0.00..30.54 rows=1 width=0)
   ->  Nested Loop  (cost=0.00..30.54 rows=1 width=0)
 Join Filter: ((wu.status <> ALL ('{2,3}'::integer[])) OR 
(wu.stop_time IS NOT NULL) OR (r.status > 2))
 ->  Index Scan using tmp_work_unit_pkey on work_unit wu  
(cost=0.00..19.61 rows=1 width=16)
   Index Cond: ((id >= 100) AND (id <= 110) AND (id 
= $0))
 ->  Index Scan using run_pkey on run r  (cost=0.00..10.91 
rows=1 width=8)
   Index Cond: (r.id = wu.run_id)
(10 rows)







caesius=# \i stmt_5.sql
explain
DELETE FROM work_active wa
where exists (
 SELECT 1
 FROM   work_unit wu
  , run r
 WHERE  wu.id = wa.wu_id
 ANDwu.id between (select min(wu_id) from work_active limit 1) and 
(select max(wu_id) from work_active limit 1)
 ANDwu.run_id = r.id
 AND(( (wu.status not in(2,3) ) OR (wu.stop_time is not null)) OR 
(r.status > 2) )
 LIMIT 1
);
   QUERY PLAN

Seq Scan on work_active wa  (cost=0.00..35071.47 rows=370 width=6)
   Filter: (subplan)
   SubPlan
 ->  Limit  (cost=16.22..46.76 rows=1 width=0)
   InitPlan
 ->  Limit  (cost=8.10..8.11 rows=1 width=0)
   InitPlan
 ->  Limit  (cost=0.00..8.10 rows=1 width=4)
   ->  Index Scan using work_active_pkey on work_active 
 (cost=0.00..5987.09 rows=739 width=4)
 Filter: (wu_id IS NOT NULL)
   ->  Result  (cost=0.00..0.01 rows=1 width=0)
 ->  Limit  (cost=8.10..8.11 rows=1 width=0)
   InitPlan
 ->  Limit  (cost=0.00..8.10 rows=1 width=4)
   ->  Index Scan Backward using work_active_pkey on 
work_active  (cost=0.00..5987.09 rows=739 w

Re: [PERFORM] what does "initplan" operation in explain output mean?

2010-08-02 Thread Mark Rostron
Thanks.
So am I right in assuming that the aggregate sub-query ( against work_active ) 
results will not assist with constraint exclusion in the sub-query against 
work_unit (if we introduce range partitions on this table)?
 Mr


-Original Message-
From: Tom Lane [mailto:t...@sss.pgh.pa.us] 
Sent: Sunday, August 01, 2010 7:08 AM
To: Mark Rostron
Cc: pgsql-performance@postgresql.org
Subject: Re: [PERFORM] what does "initplan" operation in explain output mean? 

Mark Rostron  writes:
> This message is a request for information about the "initplan" operation in 
> explain plan.

An initplan is a sub-SELECT that only needs to be executed once because it has 
no dependency on the immediately surrounding query level.  The cases you show 
here are from sub-SELECTs like this:

(select min(wu_id) from work_active limit 1)

which yields a value that's independent of anything in the outer query.
If there were an outer reference in there, you'd get a SubPlan instead, because 
the subquery would need to be done over again for each row of the outer query.

BTW, adding LIMIT 1 to an aggregate query is pretty pointless.

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


[PERFORM] what does "initplan" operation in explain output mean?

2010-08-04 Thread Mark Rostron

We are running 8.3.10 64bit.

Compare the plans below.

They all do the same thing and delete from a table named work_active (about 
500rows), which is a subset of work_unit (about 50m rows).

I want to introduce range-partitions on work_unit.id  column (serial pk), and I 
want constraint exclusion to be used.
Stmt_3 is the plan currently in use.

Stmt_4 and stmt_5 compare explain plans of two variants of the stmt (no 
partitions yet):

-  Limit the sub-query using constants (derived from a prior query of 
min() and max() against work_active), (ref stmt_4 below) or

-  Try and do something cute and do a subquery using min() and max() 
(ref stmt_5 below).


My questions are:

-  What does the "initplan" operation do? ( I can take a guess, but 
could someone give me some details, cos the docn about it is pretty sparse).

-  Will this enable constraint exclusion on the work_unit table if we 
introduce partitioning?



Thanks in adv for any help you can give me.
Mr







caesius=# \i stmt_3.sql
explain
DELETE FROM work_active wa
WHERE EXISTS (
 SELECT 1
 FROM   work_unit wu
  , run r
 WHERE  wu.id = wa.wu_id
 ANDwu.run_id = r.id
 AND(( (wu.status not in (2,3)) OR (wu.stop_time is not null)) OR 
(r.status > 2) )
 LIMIT 1
);
   QUERY PLAN

Seq Scan on work_active wa  (cost=0.00..23078.82 rows=370 width=6)
   Filter: (subplan)
   SubPlan
 ->  Limit  (cost=0.00..30.53 rows=1 width=0)
   ->  Nested Loop  (cost=0.00..30.53 rows=1 width=0)
 Join Filter: ((wu.status <> ALL ('{2,3}'::integer[])) OR 
(wu.stop_time IS NOT NULL) OR (r.status > 2))
 ->  Index Scan using tmp_work_unit_pkey on work_unit wu  
(cost=0.00..19.61 rows=1 width=16)
   Index Cond: (id = $0)
 ->  Index Scan using run_pkey on run r  (cost=0.00..10.91 
rows=1 width=8)
   Index Cond: (r.id = wu.run_id)
(10 rows)





caesius=# \i stmt_4.sql
explain
DELETE FROM work_active wa
where exists (
 SELECT 1
 FROM   work_unit wu
  , run r
 WHERE  wu.id = wa.wu_id

 ANDwu.id between 100 and 110
 ANDwu.run_id = r.id
 AND(( (wu.status not in(2,3) ) OR (wu.stop_time is not null)) OR 
(r.status > 2) )
 LIMIT 1
);
   QUERY PLAN

Seq Scan on work_active wa  (cost=0.00..22624.37 rows=362 width=6)
   Filter: (subplan)
   SubPlan
 ->  Limit  (cost=0.00..30.54 rows=1 width=0)
   ->  Nested Loop  (cost=0.00..30.54 rows=1 width=0)
 Join Filter: ((wu.status <> ALL ('{2,3}'::integer[])) OR 
(wu.stop_time IS NOT NULL) OR (r.status > 2))
 ->  Index Scan using tmp_work_unit_pkey on work_unit wu  
(cost=0.00..19.61 rows=1 width=16)
   Index Cond: ((id >= 100) AND (id <= 110) AND (id 
= $0))
 ->  Index Scan using run_pkey on run r  (cost=0.00..10.91 
rows=1 width=8)
   Index Cond: (r.id = wu.run_id)
(10 rows)







caesius=# \i stmt_5.sql
explain
DELETE FROM work_active wa
where exists (
 SELECT 1
 FROM   work_unit wu
  , run r
 WHERE  wu.id = wa.wu_id
 ANDwu.id between (select min(wu_id) from work_active limit 1) and 
(select max(wu_id) from work_active limit 1)
 ANDwu.run_id = r.id
 AND(( (wu.status not in(2,3) ) OR (wu.stop_time is not null)) OR 
(r.status > 2) )
 LIMIT 1
);
   QUERY PLAN

Seq Scan on work_active wa  (cost=0.00..35071.47 rows=370 width=6)
   Filter: (subplan)
   SubPlan
 ->  Limit  (cost=16.22..46.76 rows=1 width=0)
   InitPlan
 ->  Limit  (cost=8.10..8.11 rows=1 width=0)
   InitPlan
 ->  Limit  (cost=0.00..8.10 rows=1 width=4)
   ->  Index Scan using work_active_pkey on work_active 
 (cost=0.00..5987.09 rows=739 width=4)
 Filter: (wu_id IS NOT NULL)
   ->  Result  (cost=0.00..0.01 rows=1 width=0)
 ->  Limit  (cost=8.10..8.11 rows=1 width=0)
   InitPlan
 ->  Limit  (cost=0.00..8.10 rows=1 width=4)
   ->  Index Scan Backward using work_active_pkey on 
work_active  (cost=0.00..5987.09 rows=739 width=4)
 Filter: (wu_id IS NOT NULL)
   ->  Result  (cost=0.00..0.01 rows=1 width=0)
   ->  Nested Loop  (cost=0.00..3

Re: [PERFORM] Very poor performance

2010-08-16 Thread Mark Rostron
This is weird - is there a particular combination of memberid/answered in 
answerselectindex that has a very high rowcount?

First change I would suggest looking into would be to try changing sub-query 
logic to check existence and limit the result set of the sub-query to a single 
row

Select distinct(m.id)
>From member m
Where exists (
  Select 1
  From answerselectinstance a
  Where a.member_id = m.id
  And a.answerid between 127443 and 127448
  Limit 1
)


If member.id is a primary key, you can eliminate the "distinct" i.e. the sort.


Second would be to build a partial index on answersselectindex to index only 
the memberid's you are interested in:

"Create index  on answersselectindex(memberid) where answerid 
between 127443 and 127448"



Mr



From: pgsql-performance-ow...@postgresql.org 
[mailto:pgsql-performance-ow...@postgresql.org] On Behalf Of Aaron Burnett
Sent: Monday, August 16, 2010 6:07 PM
To: pgsql-performance@postgresql.org
Subject: [PERFORM] Very poor performance



Hi,

I'm hoping someone can offer some help here. The query and explain analyze and 
table layout are below and attached in a text file if the formatting is bad.

The query is part of a bigger query that our front end runs. This is the part 
that takes forever (84 minutes in this case) to finish and more often than not 
the front end times out. The table (answerselectinstance) has 168664317 rows 
while the member table has 626435 rows.

Postgres Version 8.25
CentOs 5.2
16 Gig RAM
192MB work_mem  (increasing to 400MB didn't change the outcome)
very light use on this server, it ais a slave to a slony replicated 
master/slave setup.

Again, apologies if the formatting got munged, the attached text file has the 
same info.

Thanking you in advance for any help and suggestions.

Aaron

explain analyze select distinct(id) from member  where id in (select memberid 
from answerselectinstance where   nswerid = 127443  OR  answerid = 127444  OR  
answerid = 127445  OR  answerid = 127446  OR  answerid = 127447  OR  answerid = 
127448   ) ;

LOG:  duration: 5076038.709 ms  statement: explain analyze select distinct(id) 
from member  where id in (select memberid from answerselectinstance where   
answerid = 127443  OR  answerid = 127444  OR  answerid = 127445  OR  answerid = 
127446  OR  answerid = 127447  OR  answerid = 127448   ) ;
  
QUERY PLAN
--
 Unique  (cost=101357.24..101357.28 rows=9 width=4) (actual 
time=5075511.974..5075911.077 rows=143520 loops=1)
   ->  Sort  (cost=101357.24..101357.26 rows=9 width=4) (actual 
time=5075511.971..5075644.323 rows=143520 loops=1)
 Sort Key: member.id
 ->  Nested Loop IN Join  (cost=0.00..101357.10 rows=9 width=4) (actual 
time=19.867..5075122.724 rows=143520 loops=1)
   ->  Seq Scan on member  (cost=0.00..78157.65 rows=626265 
width=4) (actual time=3.338..2003.582 rows=626410 loops=1)
   ->  Index Scan using asi_memberid_idx on answerselectinstance  
(cost=0.00..444.46 rows=9 width=4) (actual time=8.096..8.096 rows=0 
loops=626410)
 Index Cond: (member.id = answerselectinstance.memberid)
 Filter: ((answerid = 127443) OR (answerid = 127444) OR 
(answerid = 127445) OR (answerid = 127446) OR (answerid = 127447) OR (answerid 
= 127448))
 Total runtime: 5076034.203 ms
(9 rows)

 Column |Type | 
Modifiers
+-+
 memberid   | integer | not null
 answerid   | integer | not null
 taskinstanceid | integer | not null default 0
 created| timestamp without time zone | default "timestamp"('now'::text)
 id | integer | not null default 
nextval(('"asi_id_seq"'::text)::regclass)
Indexes:
"asi_pkey" PRIMARY KEY, btree (id)
"asi_answerid_idx" btree (answerid)
"asi_memberid_idx" btree (memberid)
"asi_taskinstanceid_idx" btree (taskinstanceid)
Triggers:
_bzzprod_cluster_denyaccess_301 BEFORE INSERT OR DELETE OR UPDATE ON 
answerselectinstance FOR EACH ROW EXECUTE PROCEDURE 
_bzzprod_cluster.denyaccess('_bzzprod_cluster')



Re: [PERFORM] Very poor performance

2010-08-17 Thread Mark Rostron
So, building the partial index will avoid the table lookup.
Currently answerselectindex only has single-column indexes on memberid and 
answerid, so any query with a predicate on both columns is gonna be forced to 
do an index lookup on one column followed by a table lookup to get the other 
one (which is what the plan shows).
This will be slower than if you can get it to lookup only an index.
I suggested a partial index (and not a two-column index) to keep it small, and 
to reduce the likelihood that it will screw up another query.
Anyway - good luck man.
?


From: Aaron Burnett [mailto:aburn...@bzzagent.com]
Sent: Monday, August 16, 2010 7:20 PM
To: Mark Rostron; pgsql-performance@postgresql.org
Subject: RE: Very poor performance



Thanks Mark,

Yeah, I apologize, I forgot to mention a couple of things.

m.id is the primary key but the biggest problem is that the query loops 626410 
times because at one time people were allowed to delete member.id rows which 
now will break the application if the a.memberid comes out and it doesn't exist 
in the member table.

The version you sent me yields pretty much the same results.

All I really SHOULD have to do is query the a.memberid column to get distinct 
memberid and the query takes less than 2 seconds. The join to the member table 
and subsequnt 600K loops are the killer. The answerselectinstance table has 166 
million rows... so the math is pretty easy on why it's painfully slow.

Other than delting data in the answerselectinstance table to get rid of the 
orphan memberid's I was hoping someone had a better way to do this.


-Original Message-----
From: Mark Rostron [mailto:mrost...@ql2.com]
Sent: Mon 8/16/2010 9:51 PM
To: Aaron Burnett; pgsql-performance@postgresql.org
Subject: RE: Very poor performance

This is weird - is there a particular combination of memberid/answered in 
answerselectindex that has a very high rowcount?

First change I would suggest looking into would be to try changing sub-query 
logic to check existence and limit the result set of the sub-query to a single 
row

Select distinct(m.id)
>From member m
Where exists (
  Select 1
  From answerselectinstance a
  Where a.member_id = m.id
  And a.answerid between 127443 and 127448
  Limit 1
)


If member.id is a primary key, you can eliminate the "distinct" i.e. the sort.


Second would be to build a partial index on answersselectindex to index only 
the memberid's you are interested in:

"Create index  on answersselectindex(memberid) where answerid 
between 127443 and 127448"



Mr



From: 
pgsql-performance-ow...@postgresql.org<mailto:pgsql-performance-ow...@postgresql.org>
 [mailto:pgsql-performance-ow...@postgresql.org] On Behalf Of Aaron Burnett
Sent: Monday, August 16, 2010 6:07 PM
To: pgsql-performance@postgresql.org<mailto:pgsql-performance@postgresql.org>
Subject: [PERFORM] Very poor performance



Hi,

I'm hoping someone can offer some help here. The query and explain analyze and 
table layout are below and attached in a text file if the formatting is bad.

The query is part of a bigger query that our front end runs. This is the part 
that takes forever (84 minutes in this case) to finish and more often than not 
the front end times out. The table (answerselectinstance) has 168664317 rows 
while the member table has 626435 rows.

Postgres Version 8.25
CentOs 5.2
16 Gig RAM
192MB work_mem  (increasing to 400MB didn't change the outcome)
very light use on this server, it ais a slave to a slony replicated 
master/slave setup.

Again, apologies if the formatting got munged, the attached text file has the 
same info.

Thanking you in advance for any help and suggestions.

Aaron

explain analyze select distinct(id) from member  where id in (select memberid 
from answerselectinstance where   nswerid = 127443  OR  answerid = 127444  OR  
answerid = 127445  OR  answerid = 127446  OR  answerid = 127447  OR  answerid = 
127448   ) ;

LOG:  duration: 5076038.709 ms  statement: explain analyze select distinct(id) 
from member  where id in (select memberid from answerselectinstance where   
answerid = 127443  OR  answerid = 127444  OR  answerid = 127445  OR  answerid = 
127446  OR  answerid = 127447  OR  answerid = 127448   ) ;
  
QUERY PLAN
--
 Unique  (cost=101357.24..101357.28 rows=9 width=4) (actual 
time=5075511.974..5075911.077 rows=143520 loops=1)
   ->  Sort  (cost=101357.24..101357.26 rows=9 width=4) (actual 
time=5075511.971..5075644.323 rows=143520 loops=1)
 Sort Key: member.id
 ->  Nested Loop IN Join  (cost=0.00..101357.10 rows=9 width=4) (actual 
time=19.867..5075122.724 rows=143520 loops=1)
   ->  Seq Scan on membe

[PERFORM] interpret statement log duration information

2010-10-25 Thread Mark Rostron
Hey

Turned on log_min_duration_statement today and started getting timings on sql 
statements (version 8.3.10).
Can anyone please tell me how to interpret the (S_nn/C_nn) information in the 
log line.

LOG:  duration: 19817.211 ms  execute S_73/C_74: (statement text) .

Thanks for your time
Mr



[PERFORM] questions regarding shared_buffers behavior

2010-11-07 Thread Mark Rostron
Question regarding the operation of the shared_buffers cache and implications 
of the pg_X_stat_tables|pg_X_stat_indexes stats.
( I am also aware that this is all complicated by the kernel cache behavior, 
however, if, for the purpose of these questions, you wouldn't mind assuming 
that we don't have a kernel cache, and therefore just focus on the behavior of 
the db cache as an isolated component, it will help - thanks in advance).

What is the procedure that postgres uses to decide whether or not a table/index 
block will be left in the shared_buffers cache at the end of the operation?

Are there any particular types of *table* access operations that will cause 
postgres to choose not to retain the table pages in shared_buffers at the end 
of the operation?
In particular, the activity tracked by:

-  Seq_scan

-  Seq_tup_read

-  Idx_tup_read

-  Idx_tup_fetch

Are there any particular types of *index* access operations that will cause 
postgres to choose not to retain the index pages in shared_buffers at the end 
of the operation?
In particular, the activity tracked by:

-  idx_scan

-  Idx_tup_read

-  Idx_tup_fetch






Re: [PERFORM] questions regarding shared_buffers behavior

2010-11-07 Thread Mark Rostron
> >
> > What is the procedure that postgres uses to decide whether or not a 
> > table/index block will be left in the shared_buffers cache at the end 
> > of the operation?
> >
>
> The only special cases are for sequential scans and VACUUM, which use 
> continuously re-use a small section of the buffer cache in some cases instead.

Thanks - the part about sequential scans and the re-use of a small section of 
shared_buffers is the bit I was interested in.
I don't suppose you would be able to tell me how large that re-useable area 
might be?

Now, with regard to the behavior of table sequential scans: do the stat values 
in seq_scan and seq_tup_read reflect actual behavior.
I assume they do, but I'm just checking - these would be updated as the result 
of real I/O as opposed to fuzzy estimates?

Obviously, the reason I am asking this is that I am noticing high machine io 
levels that would only result from sequential scan activity.
The explain output says otherwise, but the seq_scan stat value for the table 
kinda correlates.
Hence my enquiry.

Thanks in advance.
Mr




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


[PERFORM] comparison of 8.3.10 to 8.3.14 reveals unexpected difference in explain plan

2011-02-13 Thread Mark Rostron
Hi

My question is: Was there any major optimizer change between 8.3.10 to 
8.3.14?

I'm getting a difference in explain plans that I need to account for.

We are running production pg8.3.10, and are considering upgrading to 8.4.x 
(maybe 9.0), because we expected to benefit from some of the performance fixes 
of 8.4, in particular the improved use of the posix fadvise on bitmap index 
scans, mentioned in the 8.4.0 release notes.

So, I installed the latest 8.3.14 and did a comparison query between the test 
machine and prod 8.3.10, to establish a machine power difference.
To do this, I am running a query across two pg 8.3.x installs - prod 8.3.10 and 
new 8.3.14.
The database used as the test in each instance is a new database, with an 
identical data import on both.
The 8.3.10 prod machine is a faster cpu ( prod 8.3.10: 3ghz intel E5700, 
8.3.14: 2.2ghz intel E5345 (and less ram)).
The memory settings (shared_buffers, effective_cache_size, work_mem, 
maintenance_work_mem) are equal.
The results are against repeated queries, so there is no I/O component in the 
comparison - it is simply cpu and memory.

So, I expected the query response on  8.3.14 to be slower, due to being on a 
less powerful machine.
However, not so: I am actually getting a faster result on the 8.3.14 
installation (in spite of the machine being less powerful).

Looking at the explain plan, something changed.

For some reason, the "index scan" and "index cond" ops used by 8.3.10 are 
replaced by a "bitmap index scan" and "index cond" in the 8.3.14.
I'm pretty sure this is giving me the better result in 8.3.14.
(in spite of the reduced machine power).


Obviously this result is quite unexpected and I am trying to work out why.
(The only other mention that I have seen of bitmap index scan improvements was 
in the 8.4.0 release notes).

So, I am looking for information as to why this change occurred.
I reckon either it is a real version difference between 8.3.10 and 8.3.14, or 
else a difference in configuration.

Does anyone have any comments?



The 8.3.10 plan is:

explain select * from view_v1 where action_date between '2010-10-01' and 
'2010-12-08'
  QUERY PLAN
--
Hash Join  (cost=755.53..546874.02 rows=3362295 width=99)
   Hash Cond: (gp.ql2_id = dt.ql2_id)
   ->  Index Scan using gpn_nk_1 on data_stuff_new gp  (cost=0.00..495732.14 
rows=4465137 width=40)
 Index Cond: ((action_date >= '2010-10-01'::date) AND (action_date <= 
'2010-12-08'::date))
 Filter: (action_hour = ANY ('{8,10,11,12,13,14,15,16}'::integer[]))
   ->  Hash  (cost=720.80..720.80 rows=2779 width=67)
 ->  Hash Join  (cost=561.38..720.80 rows=2779 width=67)
   Hash Cond: (dtxgm.ql2_id = dt.ql2_id)
   ->  Seq Scan on data_thindt_xref_group_membership dtxgm  
(cost=0.00..93.41 rows=2779 width=10)
 Filter: (org_id = 1288539986)
   ->  Hash  (cost=451.17..451.17 rows=8817 width=57)
 ->  Seq Scan on data_thing dt  (cost=0.00..451.17 
rows=8817 width=57)
(12 rows)


The plan on 8.3.14 is:

explain select * from view_v1 where action_date between '2010-10-01' and 
'2010-12-08'

   QUERY PLAN
-
Hash Join  (cost=190151.42..684420.67 rows=3403329 width=99)
   Hash Cond: (gp.ql2_id = dt.ql2_id)
   ->  Bitmap Heap Scan on data_stuff_new gp  (cost=189395.38..633046.20 
rows=4471358 width=40)
 Recheck Cond: ((action_date >= '2010-10-01'::date) AND (action_date <= 
'2010-12-08'::date))
 Filter: (action_hour = ANY ('{8,10,11,12,13,14,15,16}'::integer[]))
 ->  Bitmap Index Scan on gpn_nk_1  (cost=0.00..188277.54 rows=7090513 
width=0)
   Index Cond: ((action_date >= '2010-10-01'::date) AND 
(action_date <= '2010-12-08'::date))
   ->  Hash  (cost=721.13..721.13 rows=2793 width=67)
 ->  Hash Join  (cost=561.38..721.13 rows=2793 width=67)
   Hash Cond: (dtxgm.ql2_id = dt.ql2_id)
   ->  Seq Scan on data_thindt_xref_group_membership dtxgm  
(cost=0.00..93.41 rows=2793 width=10)
 Filter: (org_id = 1288539986)
   ->  Hash  (cost=451.17..451.17 rows=8817 width=57)
 ->  Seq Scan on data_thing dt  (cost=0.00..451.17 
rows=8817 width=57)
(14 rows)





Re: [PERFORM] comparison of 8.3.10 to 8.3.14 reveals unexpected difference in explain plan

2011-02-13 Thread Mark Rostron
I found the difference.
Random_page_cost is 1 in the production 8.3.10, I guess weighting the decision 
to use "index scan".
Thanks for the replies, gentlemen.

> If you diff the postgresql.conf files for both installs, what's different?

In the list below, 8.3.10 parameter value is in the clear, (8.3.14 is in 
brackets)

Max_fsm_pages 819200 vs (204800)
Max_fsm_relations 4000 vs (dflt 1000)
Synchronous_commit off vs (dflt on)
Wal_buffers 256kb vs (dflt 64kb)
Checkpoint_segments 128 vs (dflt 3)
Random_page_cost 1 vs (dflt 4)#!!! Actually this is the difference 
in the explain plans
Constraint_exclusion on vs (dflt off)
 a bunch of logging parameters have been set 
Autovacuum_freeze_max_age 9 vs (dflt 2)
vacuum_freeze_min_age = 5000 vs (dflt 1)
deadlock_timeout = 20s (vs dflt 1s)
add_missing_from = on (vs dflt off)




-- 
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] comparison of 8.3.10 to 8.3.14 reveals unexpected difference in explain plan

2011-02-13 Thread Mark Rostron

> It would be easier to suggest what might be wrong if you included "EXPLAIN 
> ANALYZE" output instead of just EXPLAIN.
> It's not obvious whether 8.3 or 8.4 is estimating things better.

Thanks for reply man
Turns out random_page_cost was set low in the 8.3.10 version - when I reset it 
to 4(dflt), the explain plans are the same.
We'll double check our other queries, and then I'll see if I can reset it to 
dflt for the database.




Re: [PERFORM] amazon ec2

2011-05-03 Thread Mark Rostron
iowait is a problem on any platform that relies on spinning media, compared
to RAM.
no matter how fast a disk is, and no matter how intelligent the controller
is, you are still dealing with an access speed differential of 10^6 (speed
of disk access compared to memory access).
i have had good results by avoiding it.
if you can do this, ec2 is not too shabby, but beware - it doesn't come
free.
this is achievable under the following circumstances (and maybe there are
other ways to do this).
i use a technique of pro-actively querying enough of my anticipated result
set with a daemon procedure.
as long as the frequency of your query daemon execution is greater than that
of the competitor processes (eg ETL and other update activity), AND a
substantial part of the result set will fit in available RAM, then the
result set will be served from file system cache at the time you want it.
i have found that it doesn't take much to get this to happen, once you have
identified your critical result set.
like - you can get away with running it once/hour, and i'm still reducing
the frequency and getting good results.
this approach basically assumes a 90/10 rule - at any point in time, you
only want to access 10% of your data. if you can work out what the 10% is,
and it will fit into RAM, then you can set it up to cache it.
it also imposes no additional cost in ec2, because Amazon doesn't bill you
for CPU activity, although the large-RAM machines do cost more. Depends on
how big your critical result set is, and how much speed you need.

dont know if this helps - the success/failure of it depends on your typical
query activity, the size of your critical result set, and whether you are
able to get enough RAM to make this work.

as i said it doesn't come for free, but you can make it work.

as a further point, try also checking out greenplum - it is an excellent
postgres derivative with a very powerful free version. the reason why i
bring it up is because it offers block-level compression (with caveats - it
also doesn't come for free, so do due diligence and rtfm carefully). The
compression enabled me to improve the cache hit rate, and so you further
reduce the iowait problem.
greenplum is also a better parallel machine than postgres, so combining the
cache technique above with greenplum compression and parallel query, i have
been able to get 20:1 reduction in response times for some of our queries.
obviously introducing new database technology is a big deal, but we needed
the speed, and it kinda worked.

mr


On Tue, May 3, 2011 at 1:09 PM, Alan Hodgson  wrote:

> On May 3, 2011 12:43:13 pm you wrote:
> > On May 3, 2011, at 8:41 PM, Alan Hodgson wrote:
> > > I am also interested in tips for this. EBS seems to suck pretty bad.
> >
> > Alan, can you elaborate? Are you using PG on top of EBS?
> >
>
> Trying to, yes.
>
> Let's see ...
>
> EBS volumes seem to vary in speed. Some are relatively fast. Some are
> really
> slow. Some fast ones become slow randomly. Some are fast attached to one
> instance, but really slow attached to another.
>
> Fast being a relative term, though. The fast ones seem to be able to do
> maybe
> 400 random IOPS. And of course you can only get about 80MB/sec sequential
> access to them on a good day.
>
> Which is why I'm interested in how other people are doing it. So far EC2
> doesn't seem well suited to running databases at all.
>
> --
> Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-performance
>