Re: [PERFORM] hardware advice

2012-09-28 Thread Jeremy Harris

On 09/27/2012 10:22 PM, M. D. wrote:

On 09/27/2012 02:55 PM, Scott Marlowe wrote:

On Thu, Sep 27, 2012 at 2:46 PM, M. D.  wrote:

select item.item_id,item_plu.number,item.description,
(select number from account where asset_acct = account_id),
(select number from account where expense_acct = account_id),
(select number from account where income_acct = account_id),
(select dept.name from dept where dept.dept_id = item.dept_id) as dept,
(select subdept.name from subdept where subdept.subdept_id =
item.subdept_id) as subdept,
(select sum(on_hand) from item_change where item_change.item_id =
item.item_id) as on_hand,
(select sum(on_order) from item_change where item_change.item_id =
item.item_id) as on_order,
(select sum(total_cost) from item_change where item_change.item_id =
item.item_id) as total_cost
from item join item_plu on item.item_id = item_plu.item_id and
item_plu.seq_num = 0
where item.inactive_on is null and exists (select item_num.number from
item_num
where item_num.item_id = item.item_id)
and exists (select stocked from item_store where stocked = 'Y'
and inactive_on is null
and item_store.item_id = item.item_id)




Have you tried re-writing this query first?  Is there a reason to have
a bunch of subselects instead of joining the tables?  What pg version
are you running btw?  A newer version of pg might help too.



This query is inside an application (Quasar Accounting) written in Qt and I 
don't have access to the source code.


Is there any prospect of the planner/executor being taught to
merge each of those groups of three index scans,
to aid this sort of poor query?
--
Jeremy


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


[PERFORM] RE: [PERFORM] exponentia​l performanc​e decrease, problem with version postgres + RHEL?

2012-09-28 Thread Albe Laurenz
John Nash wrote:
> We have being doing some testing with an ISD transaction and we had
> some problems that we posted here.
> 
> The answers we got were very kind and useful but we couldn't solve the 
> problem.

Could you refer to the threads so that you don't get the same advice again?

> We have doing some investigations after this and we are thinking if is
> it possible that OS has something to do with this issue. I mean, we
> have two hosts, both of them with OS = Red Hat Enterprise Linux Server
> release 6.2 (Santiago)
> 
> But when doing "select * from version()" on the postgres shell we obtain:
> 
> sessions=# select * from version();
>version
> --
> 
>  PostgreSQL 9.1.3 on x86_64-unknown-linux-gnu, compiled by gcc (GCC)
> 4.4.6 20110731 (Red Hat 4.4.6-3), 64-bit
> (1 row)
> 
> We don't understand why in here it's written "(Red Hat 4.4.6-3)".
> 
> Is it possible that we have installed a postgres' version that it's
> not perfect for the OS?

It means that the PostgreSQL you are using was compiled with a
compiler that was compiled on RHEL4.  Shouldn't be a problem.

> But if this is a problem, why are we obtaining a normal perform on a
> host and an exponential performance decrease on another?
> 
> And how can we obtain a normal performance when launching the program
> which does the queries from another host (remote url) but when
> launching it in the same host we obtain this decrease on the
> performance?

Try to identify the bottleneck.
Is it disk I/O, CPU, memory or something else?

> name   |
> current_setting
> 
> --+---
> -
> --
>  version  | PostgreSQL 9.1.3 on
> x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.4.6 20110731 (Red
> Hat
>  4.4.6-3), 64-bit
>  archive_mode | off
>  client_encoding  | UTF8
>  fsync| on
>  lc_collate   | en_US.UTF-8
>  lc_ctype | en_US.UTF-8
>  listen_addresses | *
>  log_directory| pg_log
>  log_filename | postgresql-%a.log
>  log_rotation_age | 1d
>  log_rotation_size| 0
>  log_truncate_on_rotation | on
>  logging_collector| on
>  max_connections  | 100
>  max_stack_depth  | 2MB
>  port | 50008
>  server_encoding  | UTF8
>  shared_buffers   | 32MB

Now that sticks out as being pretty small.
Try 1/4 of the memory available for the database, but not
more than 2 GB.

>  synchronous_commit   | on
>  TimeZone | Europe/Madrid
>  wal_buffers  | 64kB

That's also pretty small.

>  wal_sync_method  | fsync
> (22 rows)

Yours,
Laurenz Albe

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


[PERFORM] "Select * " on 12-18M row table from remote machine thru JDBC - Performance nose-dives after 10M-ish records

2012-09-28 Thread antthelimey
On machine 1 - a table that contains between 12 and 18 million rows
On machine 2 - a Java app that calls Select * on the table, and writes it
into a Lucene index

Originally had a fetchSize of 10,000 and would take around 38 minutes for 12
million, 50 minutes for 16ish million to read it all & write it all back out
as the lucene index

One day it started taking 4 hours. If something changed, we dont know what
it was

We tracked it down to, after 10 million or so rows, the Fetch to get the
next 10,000 rows from the DB goes from like 1 second to 30 seconds, and
stays there

After spending a week of two devs &  DBA trying to solve this, we eventually
"solved" it by upping the FetchRowSize in the JDBC call to 50,000

It was performing well enough again for a few weeks

then...one day... it started taking 4 hours again

we tried upping the shared_buffer from 16GB to 20GB

And last night... it took 7 hours

we are using PGSQL 9.1

does anyone have ANY ideas?!

thanks much



--
View this message in context: 
http://postgresql.1045698.n5.nabble.com/Select-on-12-18M-row-table-from-remote-machine-thru-JDBC-Performance-nose-dives-after-10M-ish-records-tp5725853.html
Sent from the PostgreSQL - performance mailing list archive at Nabble.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] "Select * " on 12-18M row table from remote machine thru JDBC - Performance nose-dives after 10M-ish records

2012-09-28 Thread Deron
I think the best advice I can think of is to go back to the basics.  Tools
like sar and top and look at logs.   Changing random settings on both the
client and server seems like guessing.  I find it unlikely that the changes
you made (jdbc and shared buffers) had the effects you noticed.  Determine
if it is I/O, CPU, or network.   Put all your settings back to the way they
were.  If the DB did not change, then look at OS and network.

Deron
On Sep 28, 2012 6:53 AM, "antthelimey"  wrote:

> On machine 1 - a table that contains between 12 and 18 million rows
> On machine 2 - a Java app that calls Select * on the table, and writes it
> into a Lucene index
>
> Originally had a fetchSize of 10,000 and would take around 38 minutes for
> 12
> million, 50 minutes for 16ish million to read it all & write it all back
> out
> as the lucene index
>
> One day it started taking 4 hours. If something changed, we dont know what
> it was
>
> We tracked it down to, after 10 million or so rows, the Fetch to get the
> next 10,000 rows from the DB goes from like 1 second to 30 seconds, and
> stays there
>
> After spending a week of two devs &  DBA trying to solve this, we
> eventually
> "solved" it by upping the FetchRowSize in the JDBC call to 50,000
>
> It was performing well enough again for a few weeks
>
> then...one day... it started taking 4 hours again
>
> we tried upping the shared_buffer from 16GB to 20GB
>
> And last night... it took 7 hours
>
> we are using PGSQL 9.1
>
> does anyone have ANY ideas?!
>
> thanks much
>
>
>
> --
> View this message in context:
> http://postgresql.1045698.n5.nabble.com/Select-on-12-18M-row-table-from-remote-machine-thru-JDBC-Performance-nose-dives-after-10M-ish-records-tp5725853.html
> Sent from the PostgreSQL - performance mailing list archive at Nabble.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] hardware advice

2012-09-28 Thread k...@rice.edu
On Thu, Sep 27, 2012 at 03:50:33PM -0500, Shaun Thomas wrote:
> On 09/27/2012 03:44 PM, Scott Marlowe wrote:
> 
> >This 100x this.  We used to buy our boxes from aberdeeninc.com and got
> >a 5 year replacement parts warranty included.  We spent ~$10k on a
> >server that was right around $18k from dell for the same numbers and a
> >3 year warranty.
> 
> Whatever you do, go for the Intel ethernet adaptor option. We've had
> so many headaches with integrated broadcom NICs. :(
> 
+++1 Sigh.

Ken


-- 
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] hardware advice

2012-09-28 Thread Craig James
On 9/27/2012 1:56 PM, M. D. wrote:
>>
>> I'm in Belize, so what I'm considering is from ebay, where it's unlikely
>> that I'll get the warranty.  Should I consider some other brand rather? To
>> build my own or buy custom might be an option too, but I would not get any
>> warranty.

Your best warranty would be to have the confidence to do your own
repairs, and to have the parts on hand.  I'd seriously consider
putting your own system together.  Maybe go to a few sites with
pre-configured machines and see what parts they use.  Order those,
screw the thing together yourself, and put a spare of each critical
part on your shelf.

A warranty is useless if you can't use it in a timely fashion.  And
you could easily get better reliability by spending the money on spare
parts.  I'd bet that for the price of a warranty you can buy a spare
motherboard, a few spare disks, a memory stick or two, a spare power
supply, and maybe even a spare 3WARE RAID controller.

Craig


-- 
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] hardware advice

2012-09-28 Thread David Boreham

On 9/28/2012 9:46 AM, Craig James wrote:

Your best warranty would be to have the confidence to do your own
repairs, and to have the parts on hand.  I'd seriously consider
putting your own system together.  Maybe go to a few sites with
pre-configured machines and see what parts they use.  Order those,
screw the thing together yourself, and put a spare of each critical
part on your shelf.

This is what I did for years, but after taking my old parts collection 
to the landfill a few times, realized I may as well just buy N+1 
machines and keep zero spares on the shelf. That way I get a spare 
machine available for use immediately, and I know the parts are working 
(parts on the shelf may be defective). If something breaks, I use the 
spare machine until the replacement parts arrive.


Note in addition that a warranty can be extremely useful in certain 
organizations as a vehicle of blame avoidance (this may be its primary 
purpose in fact). If I buy a bunch of machines that turn out to have 
buggy NICs, well that's my fault and I can kick myself since I own the 
company, stay up late into the night reading kernel code, and buy new 
NICs. If I have an evil Dilbertian boss, then well...I'd be seriously 
thinking about buying Dell boxes in order to blame Dell rather than 
myself, and be able to say "everything is warrantied" if badness goes 
down. Just saying...





--
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] hardware advice

2012-09-28 Thread M. D.

On 09/28/2012 09:57 AM, David Boreham wrote:

On 9/28/2012 9:46 AM, Craig James wrote:

Your best warranty would be to have the confidence to do your own
repairs, and to have the parts on hand.  I'd seriously consider
putting your own system together.  Maybe go to a few sites with
pre-configured machines and see what parts they use.  Order those,
screw the thing together yourself, and put a spare of each critical
part on your shelf.

This is what I did for years, but after taking my old parts collection 
to the landfill a few times, realized I may as well just buy N+1 
machines and keep zero spares on the shelf. That way I get a spare 
machine available for use immediately, and I know the parts are 
working (parts on the shelf may be defective). If something breaks, I 
use the spare machine until the replacement parts arrive.


Note in addition that a warranty can be extremely useful in certain 
organizations as a vehicle of blame avoidance (this may be its primary 
purpose in fact). If I buy a bunch of machines that turn out to have 
buggy NICs, well that's my fault and I can kick myself since I own the 
company, stay up late into the night reading kernel code, and buy new 
NICs. If I have an evil Dilbertian boss, then well...I'd be seriously 
thinking about buying Dell boxes in order to blame Dell rather than 
myself, and be able to say "everything is warrantied" if badness goes 
down. Just saying...


I'm kinda in the latter shoes.  Dell is the only thing that is trusted 
in my organisation.  If I would build my own, I would be fully blamed 
for anything going wrong in the next 3 years. Thanks everyone for your 
input.  Now my final choice will be if my budget allows for the latest 
and fastest, else I'm going for the x5690.  I don't have hundreds of 
users, so I think the x5690 should do a pretty good job handling the load.





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


[PERFORM] Possible Performance Regression with Transitive Comparisons vs. Constants

2012-09-28 Thread Shaun Thomas

Hey guys,

I ran into this while we were working on an upgrade project. We're 
moving from 8.2 (don't ask) to 9.1, and started getting terrible 
performance for some queries. I've managed to boil it down to a test case:


create temp table my_foo as
select a.id, '2012-01-01'::date + (random()*365)::int AS created_dt
  from generate_series(1,5000) as a(id);

create temp table my_bar as
select b.id, (random()*4999)::int + 1 as aid,
   '2012-01-01'::date + (random()*365)::int AS created_dt
  from generate_series(1,50) as b(id);

analyze my_foo;
analyze my_bar;

create index idx_foo_id on my_foo (id);
create index idx_foo_const on my_foo (created_dt);

create index idx_bar_id on my_bar(id);
create index idx_bar_aid on my_bar(aid);
create index idx_bar_const on my_bar (created_dt);


Ok, simple enough, right? Now do this:


explain analyze
select b.*
  from my_foo a, my_bar b
 where a.created_dt = '2012-05-05'
   and b.created_dt between a.created_dt
   and a.created_dt + interval '1 month';

explain analyze
select b.*
  from my_foo a, my_bar b
 where a.created_dt = '2012-05-05'
   and b.created_dt between '2012-05-05'
   and '2012-05-05'::date + interval '1 month';


These do not create the same query plan, which itself is odd. But the 
other thing, is that query 1 is about 4-8x slower than query 2, but only 
when I test it on PostgreSQL 9.1. When I test it on 8.2 (eww) they're 
about equal in performance. I should note that the plan for both cases 
in 8.2, performs better than query 1 in 9.1.


So I've got two questions:

1. Is it normal for trivially equal values to be non-optimal like this?
2. What on earth happened between 8.2 and 9.1 that made performance 
worse for this test case?


Just to address any questions, I've tested this in multiple 
environments, and it's always consistent. 9.1 performs worse than 8.2 
here, so long as you rely on PostgreSQL to make the equivalence instead 
of doing it manually.



--
Shaun Thomas
OptionsHouse | 141 W. Jackson Blvd. | Suite 500 | Chicago IL, 60604
312-444-8534
stho...@optionshouse.com

__

See http://www.peak6.com/email_disclaimer/ for terms and conditions related to 
this email


--
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] Possible Performance Regression with Transitive Comparisons vs. Constants

2012-09-28 Thread Tom Lane
Shaun Thomas  writes:
> I ran into this while we were working on an upgrade project. We're 
> moving from 8.2 (don't ask) to 9.1, and started getting terrible 
> performance for some queries. I've managed to boil it down to a test case:

9.1.what?  For me, 8.2.23 and 9.1.6 produce the same plan and just about
the same runtime for your query 1.  For query 2, 9.1.6 prefers to stick
in a Materialize node, which cuts the runtime 30% or so --- but if I set
enable_material to off then I get the same plan and runtime as with 8.2.

Perhaps you should show the EXPLAIN ANALYZE outputs you're actually
getting, rather than assuming others will get the same thing.

regards, tom lane

(PS: it does seem that HEAD has got some kind of issue here, because
it's picking a plain not bitmap indexscan.  I'll go look at that.
But I don't see that misbehavior in 9.1.)


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


[PERFORM] Query plan, nested EXISTS

2012-09-28 Thread Matt Daw
Howdy, I've been debugging a client's slow query today and I'm curious
about the query plan. It's picking a plan that hashes lots of rows from the
versions table (on v9.0.10)...

EXPLAIN ANALYZE
SELECT COUNT(*) FROM notes a WHERE
a.project_id = 114 AND
EXISTS (
SELECT 1 FROM note_links b
WHERE
b.note_id = a.id AND
b.entity_type = 'Version' AND
EXISTS (
SELECT 1 FROM versions c
WHERE
c.id = b.entity_id AND
c.code ILIKE '%comp%' AND
c.retirement_date IS NULL
) AND
b.retirement_date IS NULL
)


 QUERY PLAN

-
 Aggregate  (cost=833177.30..833177.31 rows=1 width=0) (actual
time=10806.416..10806.416 rows=1 loops=1)
   ->  Hash Semi Join  (cost=747004.15..833154.86 rows=8977 width=0)
(actual time=10709.343..10806.344 rows=894 loops=1)
 Hash Cond: (a.id = b.note_id)
 ->  Index Scan using notes_retirement_date_project on notes a
 (cost=0.00..66725.10 rows=12469 width=4) (actual time=12.213..71.199
rows=12469 loops=1)
   Index Cond: (project_id = 114)
 ->  Hash  (cost=723749.35..723749.35 rows=1417424 width=4) (actual
time=10696.192..10696.192 rows=227261 loops=1)
   Buckets: 65536  Batches: 4  Memory Usage: 2016kB
   ->  Hash Semi Join  (cost=620007.75..723749.35 rows=1417424
width=4) (actual time=8953.460..10645.714 rows=227261 loops=1)
 Hash Cond: (b.entity_id = c.id)
 ->  Seq Scan on note_links b  (cost=0.00..71849.56
rows=1417424 width=8) (actual time=0.075..628.183 rows=1509795 loops=1)
   Filter: ((retirement_date IS NULL) AND
((entity_type)::text = 'Version'::text))
 ->  Hash  (cost=616863.62..616863.62 rows=251530
width=4) (actual time=8953.327..8953.327 rows=300115 loops=1)
   Buckets: 32768  Batches: 1  Memory Usage: 10551kB
   ->  Seq Scan on versions c
 (cost=0.00..616863.62 rows=251530 width=4) (actual time=176.590..8873.588
rows=300115 loops=1)
 Filter: ((retirement_date IS NULL) AND
((code)::text ~~* '%comp%'::text))
 Total runtime: 10810.479 ms
(16 rows)

However, I can trick it into a better plan by adding LIMIT 1 into the inner
EXISTS:

EXPLAIN ANALYZE
SELECT COUNT(*) FROM notes a WHERE
a.project_id = 114 AND
EXISTS (
SELECT 1 FROM note_links b
WHERE
b.note_id = a.id AND
b.entity_type = 'Version' AND
EXISTS (
SELECT 1 FROM versions c
WHERE
c.id = b.entity_id AND
c.code ILIKE '%comp%' AND
c.retirement_date IS NULL
LIMIT 1
) AND
b.retirement_date IS NULL
)


 QUERY PLAN


 Aggregate  (cost=372820.37..372820.38 rows=1 width=0) (actual
time=139.430..139.430 rows=1 loops=1)
   ->  Nested Loop Semi Join  (cost=0.00..372809.15 rows=4488 width=0)
(actual time=9.735..139.333 rows=894 loops=1)
 ->  Index Scan using notes_retirement_date_project on notes a
 (cost=0.00..66725.10 rows=12469 width=4) (actual time=9.699..67.263
rows=12469 loops=1)
   Index Cond: (project_id = 114)
 ->  Index Scan using note_links_note on note_links b
 (cost=0.00..24.54 rows=1 width=4) (actual time=0.006..0.006 rows=0
loops=12469)
   Index Cond: (b.note_id = a.id)
   Filter: ((b.retirement_date IS NULL) AND
((b.entity_type)::text = 'Version'::text) AND (SubPlan 1))
   SubPlan 1
 ->  Limit  (cost=0.00..9.04 rows=1 width=0) (actual
time=0.003..0.003 rows=0 loops=11794)
   ->  Index Scan using versions_pkey on versions c
 (cost=0.00..9.04 rows=1 width=0) (actual time=0.003..0.003 rows=0
loops=11794)
 Index Cond: (id = $0)
 Filter: ((retirement_date IS NULL) AND
((code)::text ~~* '%comp%'::text))
 Total runtime: 139.465 ms
(13 rows)


Unfortunately, a couple other queries I tested got slower by adding the
LIMIT so I don't think that's going to be a good workaround. It doesn't
appear to be related to ILIKE, because I tried a straight equals against
another un-indexed column of versions and still get a slow plan (and adding
the LIMIT to this one made it fast too):

EXPLAIN ANALYZE
SELECT COUNT(*) FROM notes a WHERE
a.project_id = 114 AND
EXISTS (
SELECT 1 FROM note_links b
WHERE
b.note_id = a.id AND
b.entity_type = 'Version' AND
EXISTS (
SELECT 1 FROM versions c
WHERE
c.id = b.entity_id AND
c.sg_status_list = 'ip' AND
c.retirement_date IS NULL
) AND
b.retirement_date IS NULL
)


QUERY PLAN

---

Re: [PERFORM] Possible Performance Regression with Transitive Comparisons vs. Constants

2012-09-28 Thread Shaun Thomas

On 09/28/2012 03:35 PM, Tom Lane wrote:


9.1.what?  For me, 8.2.23 and 9.1.6 produce the same plan and just
about the same runtime for your query 1.


I withdraw that part of my question. I apparently didn't look closely 
enough at the actual output. I was basing the version assumption on the 
query speed on the new server, when it was probably due to cache effects.


The first part of the question stands, though... Why isn't the optimizer 
substituting these values? a.created_date should be exactly equivalent 
to '2012-05-05', but it's clearly not being treated that way.


With the full substitutions, I'm seeing things like this:

http://explain.depesz.com/s/3T4

With the column names, it's this:

http://explain.depesz.com/s/Fq7

This is on 8.2, but the behavior is the same on 9.1. From 130s to 23s 
simply by substituting the constant wherever the column name is 
encountered. For reference, the queries are, slow:


select a.id, f.ezorder_id
  from reporting.account a
  join ezorder f on f.account_id = a.account_id
 where a.process_date = '2012-09-27'
   and f.date_created between a.process_date - interval '6 months'
   and a.process_date
   and a.row_out is null

And fast:

select a.id, f.ezorder_id
  from reporting.account a
  join ezorder f on f.account_id = a.account_id
 where a.process_date = '2012-09-27'
   and f.date_created between '2012-09-27'::date - interval '6 months'
   and '2012-09-27'
   and a.row_out is null

We discovered this during the upgrade, but it seems to equally apply to 
both 8.2 and 9.1. I've been telling the devs to replace any of these 
they find all day. I can't quite say why we never "noticed" this before, 
but it got exposed today pretty plainly. If this were a compiler, I'd 
have expected it to treat the values as equivalent, but that's clearly 
not what's happening.


--
Shaun Thomas
OptionsHouse | 141 W. Jackson Blvd. | Suite 500 | Chicago IL, 60604
312-444-8534
stho...@optionshouse.com

__

See http://www.peak6.com/email_disclaimer/ for terms and conditions related to 
this email


--
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] Query plan, nested EXISTS

2012-09-28 Thread Tom Lane
Matt Daw  writes:
> Howdy, I've been debugging a client's slow query today and I'm curious
> about the query plan. It's picking a plan that hashes lots of rows from the
> versions table (on v9.0.10)...

> EXPLAIN ANALYZE
> SELECT COUNT(*) FROM notes a WHERE
> a.project_id = 114 AND
> EXISTS (
> SELECT 1 FROM note_links b
> WHERE
> b.note_id = a.id AND
> b.entity_type = 'Version' AND
> EXISTS (
> SELECT 1 FROM versions c
> WHERE
> c.id = b.entity_id AND
> c.code ILIKE '%comp%' AND
> c.retirement_date IS NULL
> ) AND
> b.retirement_date IS NULL
> )

I think the real problem here is that 9.0 is incapable of avoiding a
full table scan on "note_links", which means it doesn't really have any
better option than to do the inner EXISTS as a full-table semijoin.
This is because it can't push a.id down through two levels of join, and
because the semijoins don't commute, there's no way to get a.id into the
scan of note_links to pull out only the useful rows.  The hack with
LIMIT avoids this problem by preventing the inner EXISTS from being
treated as a full-fledged semijoin; but of course that hack leaves you
vulnerable to very bad plans if the statistics are such that a nestloop
join isn't the best bet for the inner EXISTS.

The work I did for parameterized paths in 9.2 was intended to address
exactly this type of scenario.  I would be interested to know if 9.2
does this any better for you.

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] Query plan, nested EXISTS

2012-09-28 Thread Matt Daw
Hi Tom, thank you very much. I'll load these tables onto a 9.2 instance and
report back.

Matt

On Fri, Sep 28, 2012 at 2:44 PM, Tom Lane  wrote:

> Matt Daw  writes:
> > Howdy, I've been debugging a client's slow query today and I'm curious
> > about the query plan. It's picking a plan that hashes lots of rows from
> the
> > versions table (on v9.0.10)...
>
> > EXPLAIN ANALYZE
> > SELECT COUNT(*) FROM notes a WHERE
> > a.project_id = 114 AND
> > EXISTS (
> > SELECT 1 FROM note_links b
> > WHERE
> > b.note_id = a.id AND
> > b.entity_type = 'Version' AND
> > EXISTS (
> > SELECT 1 FROM versions c
> > WHERE
> > c.id = b.entity_id AND
> > c.code ILIKE '%comp%' AND
> > c.retirement_date IS NULL
> > ) AND
> > b.retirement_date IS NULL
> > )
>
> I think the real problem here is that 9.0 is incapable of avoiding a
> full table scan on "note_links", which means it doesn't really have any
> better option than to do the inner EXISTS as a full-table semijoin.
> This is because it can't push a.id down through two levels of join, and
> because the semijoins don't commute, there's no way to get a.id into the
> scan of note_links to pull out only the useful rows.  The hack with
> LIMIT avoids this problem by preventing the inner EXISTS from being
> treated as a full-fledged semijoin; but of course that hack leaves you
> vulnerable to very bad plans if the statistics are such that a nestloop
> join isn't the best bet for the inner EXISTS.
>
> The work I did for parameterized paths in 9.2 was intended to address
> exactly this type of scenario.  I would be interested to know if 9.2
> does this any better for you.
>
> regards, tom lane
>


Re: [PERFORM] Possible Performance Regression with Transitive Comparisons vs. Constants

2012-09-28 Thread Tom Lane
Shaun Thomas  writes:
> The first part of the question stands, though... Why isn't the optimizer 
> substituting these values? a.created_date should be exactly equivalent 
> to '2012-05-05', but it's clearly not being treated that way.

No version of Postgres has ever substituted constants in the way you're
imagining, and I wouldn't hold my breath waiting for it to happen.  The
reason is that "x = constant" only creates a requirement for x to be
btree-equal to the constant, and btree equality doesn't guarantee
equality for all purposes.  In this example we'd have to assume that
btree-equality guaranteed identical results from the date + interval
addition operator.  While that happens to be true for this operator,
the planner can't know that.

A real-world example of the kind of case I'm worried about is that in
IEEE-spec float arithmetic, minus zero and plus zero compare equal ---
but there are functions that give different results for the two values.
Another is that the char(n) type's equality operator will say that
'foo' and 'foo  ' are equal, but those values are definitely
distinguishable by some operations, eg length().

There are some cases where the planner can effectively propagate
constants, but they rely on transitivity of btree equality operators.
For instance if we have x = constant and x = y, with compatible equality
operators, we can deduce y = constant.  But that doesn't imply that y
*is* the constant, just that it's btree-equal to it.

There have been some discussions of inventing a stronger notion of
equality than btree equality, so that we could know when it's safe to
make this type of substitution; but nothing's been done about that.
Personally I think it's fairly rare that any real win would come from
this type of constant substitution, and so it's very likely that adding
it would just create a net drag on performance (because of the added
planner cycles spent looking for substitution opportunities, which would
happen in every query whether it got any benefit or not).

Another point here is that at least for the one side of your BETWEEN
operator, b.created_dt >= a.created_dt, we could in fact combine that
with a.created_dt = '2012-05-05' to deduce b.created_dt >= '2012-05-05',
because we know from the btree opclass for dates that these = and >=
operators have compatible semantics.  Again though, it seems likely that
the cost of looking for such opportunities would outweigh the benefits.
In this particular example I don't think it'd do much good --- the
reason the planner isn't picking a plan similar to the "fast" one is
that it doesn't know that the BETWEEN with variable limits will select
only a relatively small part of the table.  Providing a constant limit
for just one side wouldn't fix that.

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] Query plan, nested EXISTS

2012-09-28 Thread Matt Daw
Hi Tom, v9.2.1 looks good!

 Aggregate  (cost=420808.99..420809.00 rows=1 width=0) (actual
time=147.345..147.345 rows=1 loops=1)
   ->  Nested Loop Semi Join  (cost=0.00..420786.71 rows=8914 width=0)
(actual time=13.847..147.219 rows=894 loops=1)
 ->  Index Scan using notes_retirement_date_project on notes a
 (cost=0.00..67959.22 rows=12535 width=4) (actual time=13.811..71.741
rows=12469 loops=1)
   Index Cond: (project_id = 114)
 ->  Nested Loop Semi Join  (cost=0.00..28.14 rows=1 width=4)
(actual time=0.006..0.006 rows=0 loops=12469)
   ->  Index Scan using note_links_note on note_links b
 (cost=0.00..12.37 rows=1 width=8) (actual time=0.002..0.002 rows=1
loops=12469)
 Index Cond: (note_id = a.id)
 Filter: ((retirement_date IS NULL) AND
((entity_type)::text = 'Version'::text))
 Rows Removed by Filter: 1
   ->  Index Scan using versions_pkey on versions c
 (cost=0.00..15.76 rows=1 width=4) (actual time=0.003..0.003 rows=0
loops=11794)
 Index Cond: (id = b.entity_id)
 Filter: ((retirement_date IS NULL) AND ((code)::text
~~* '%comp%'::text))
 Rows Removed by Filter: 1
 Total runtime: 147.411 ms
(14 rows)

On Fri, Sep 28, 2012 at 2:47 PM, Matt Daw  wrote:

> Hi Tom, thank you very much. I'll load these tables onto a 9.2 instance
> and report back.
>
> Matt
>
>
> On Fri, Sep 28, 2012 at 2:44 PM, Tom Lane  wrote:
>
>> Matt Daw  writes:
>> > Howdy, I've been debugging a client's slow query today and I'm curious
>> > about the query plan. It's picking a plan that hashes lots of rows from
>> the
>> > versions table (on v9.0.10)...
>>
>> > EXPLAIN ANALYZE
>> > SELECT COUNT(*) FROM notes a WHERE
>> > a.project_id = 114 AND
>> > EXISTS (
>> > SELECT 1 FROM note_links b
>> > WHERE
>> > b.note_id = a.id AND
>> > b.entity_type = 'Version' AND
>> > EXISTS (
>> > SELECT 1 FROM versions c
>> > WHERE
>> > c.id = b.entity_id AND
>> > c.code ILIKE '%comp%' AND
>> > c.retirement_date IS NULL
>> > ) AND
>> > b.retirement_date IS NULL
>> > )
>>
>> I think the real problem here is that 9.0 is incapable of avoiding a
>> full table scan on "note_links", which means it doesn't really have any
>> better option than to do the inner EXISTS as a full-table semijoin.
>> This is because it can't push a.id down through two levels of join, and
>> because the semijoins don't commute, there's no way to get a.id into the
>> scan of note_links to pull out only the useful rows.  The hack with
>> LIMIT avoids this problem by preventing the inner EXISTS from being
>> treated as a full-fledged semijoin; but of course that hack leaves you
>> vulnerable to very bad plans if the statistics are such that a nestloop
>> join isn't the best bet for the inner EXISTS.
>>
>> The work I did for parameterized paths in 9.2 was intended to address
>> exactly this type of scenario.  I would be interested to know if 9.2
>> does this any better for you.
>>
>> regards, tom lane
>>
>
>


[PERFORM] NestedLoops over BitmapScan question

2012-09-28 Thread Виктор Егоров
Greetings.

I have a small monitoring query on the following tables:
select relname,relpages,reltuples::numeric(12) from pg_class where relname
in ('meta_version','account') order by 1;
   relname| relpages | reltuples
--+--+---
 account  | 3235 |197723
 meta_version |   710068 |  32561200
(2 rows)

The logical “body” of the query is:
select count(*) from meta_version where account_id in (select account_id
from account where customer_id = 8608064);

I know that due to the data distribution (above customer's accounts are
used in 45% of the meta_version table) I
cannot expect fast results. But I have another question.

With default default_statistics_target I get the following plan:
http://explain.depesz.com/s/jri

In order to get better estimates, I've increased statistics targets to 200
for account.customer_id and meta_version.account_id.
Now I have the following plan:
http://explain.depesz.com/s/YZJ

Second query takes twice more time.
My questions are:
- why with better statistics planner chooses to do a SeqScan in favor of
BitmapIndexScan inside the NestedLoops?
- is it possible to adjust this decision by changing other GUCs, perhaps
costs?
- would it be correct to adjust seq_page_cost and random_page_cost based on
the IOPS of the underlying disks?
  any other metrics should be considered?

I'm running on a:
name|
 current_setting
+---
 version| PostgreSQL 9.1.6 on x86_64-unknown-linux-gnu,
compiled by gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-52), 64-bit
 archive_command| test ! -f $PG_WAL/%f && cp %p $PG_WAL/%f
 archive_mode   | on
 bgwriter_delay | 50ms
 bgwriter_lru_maxpages  | 200
 checkpoint_segments| 25
 checkpoint_timeout | 30min
 client_encoding| UTF8
 effective_cache_size   | 8GB
 hot_standby| on
 lc_collate | en_US.UTF-8
 lc_ctype   | en_US.UTF-8
 listen_addresses   | *
 log_checkpoints| on
 log_connections| on
 log_destination| csvlog
 log_directory  | ../../log/CLUSTER
 log_disconnections | on
 log_file_mode  | 0640
 log_filename   | pg-%Y%m%d_%H%M%S.log
 log_line_prefix| %u:%d:%a:%h:%c:%x:%t>
 log_lock_waits | on
 log_min_duration_statement | 300ms
 log_rotation_age   | 1d
 log_rotation_size  | 0
 log_temp_files | 20MB
 logging_collector  | on
 maintenance_work_mem   | 512MB
 max_connections| 200
 max_prepared_transactions  | 0
 max_stack_depth| 2MB
 max_wal_senders| 2
 port   | 9120
 server_encoding| UTF8
 shared_buffers | 5GB
 silent_mode| on
 ssl| on
 ssl_renegotiation_limit| 0
 tcp_keepalives_idle| 0
 temp_buffers   | 256MB
 TimeZone   | US/Eastern
 wal_buffers| 512kB
 wal_keep_segments  | 0
 wal_level  | hot_standby
 wal_sender_delay   | 1s
 work_mem   | 32MB

Regards.

-- 
Victor Y. Yegorov


Re: [PERFORM] hardware advice

2012-09-28 Thread Scott Marlowe
On Fri, Sep 28, 2012 at 11:33 AM, M. D.  wrote:
> On 09/28/2012 09:57 AM, David Boreham wrote:
>>
>> On 9/28/2012 9:46 AM, Craig James wrote:
>>>
>>> Your best warranty would be to have the confidence to do your own
>>> repairs, and to have the parts on hand.  I'd seriously consider
>>> putting your own system together.  Maybe go to a few sites with
>>> pre-configured machines and see what parts they use.  Order those,
>>> screw the thing together yourself, and put a spare of each critical
>>> part on your shelf.
>>>
>> This is what I did for years, but after taking my old parts collection to
>> the landfill a few times, realized I may as well just buy N+1 machines and
>> keep zero spares on the shelf. That way I get a spare machine available for
>> use immediately, and I know the parts are working (parts on the shelf may be
>> defective). If something breaks, I use the spare machine until the
>> replacement parts arrive.
>>
>> Note in addition that a warranty can be extremely useful in certain
>> organizations as a vehicle of blame avoidance (this may be its primary
>> purpose in fact). If I buy a bunch of machines that turn out to have buggy
>> NICs, well that's my fault and I can kick myself since I own the company,
>> stay up late into the night reading kernel code, and buy new NICs. If I have
>> an evil Dilbertian boss, then well...I'd be seriously thinking about buying
>> Dell boxes in order to blame Dell rather than myself, and be able to say
>> "everything is warrantied" if badness goes down. Just saying...
>>
> I'm kinda in the latter shoes.  Dell is the only thing that is trusted in my
> organisation.  If I would build my own, I would be fully blamed for anything
> going wrong in the next 3 years. Thanks everyone for your input.  Now my
> final choice will be if my budget allows for the latest and fastest, else
> I'm going for the x5690.  I don't have hundreds of users, so I think the
> x5690 should do a pretty good job handling the load.

If people in your organization trust Dell, they just haven't dealt
with them enough.


-- 
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] Postgres becoming slow, only full vacuum fixes it

2012-09-28 Thread Thomas Kellerer

Kiriakos Tsourapas, 25.09.2012 13:01:

Thank you,

I will take this into consideration, since upgrading to 9 will be much harder I 
assume...



I think an upgrade from 8.3 to 8.4 was "harder" due to the removal of a lot of 
implicit type casts.
8.4 to 9.x shouldn't be that problematic after all (but will take longer due to 
the required dump/reload)






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


[PERFORM] wrong join result set estimate

2012-09-28 Thread Evgeny Shishkin
Hello,

i have a problem with relatively easy query.

EXPLAIN ANALYZE SELECT content.* FROM content JOIN blog ON blog.id = 
content.blog_id JOIN community_prop ON blog.id = community_prop.blog_id JOIN 
community ON community.id = community_prop.id WHERE community.id IN (33, 55, 
61, 1741, 75, 90, 106, 180, 228, 232, 256, 310, 388, 404, 504, 534, 536, 666, 
700, 768, 824, 832, 855, 873, 898, 962, 1003, 1008, 1027, 1051, 1201, 1258, 
1269, 1339, 1355, 1360, 1383, 1390, 1430, 1505, 1506, 1530, 1566, 1578, 1616, 
1678, 1701, 1713, 1723, 1821, 1842, 1880, 1882, 1894, 1973, 2039, 2069, 2106, 
2130, 2204, 2226, 2236, 2238, 2263, 2272, 2310, 2317, 2327, 2353, 2360, 2401, 
2402, 2409, 2419, 2425, 2426, 2438, 2440, 2452, 2467, 2494, 2514, 2559, 2581, 
2653, 2677, 2679, 2683, 2686, 2694, 2729, 2732, 2739, 2779, 2785, 2795, 2821, 
2831, 2839, 2862, 2864, 2866, 2882, 2890, 2905, 2947, 2962, 2964, 2978, 2981, 
3006, 3016, 3037, 3039, 3055, 3060, 3076, 3112, 3124, 3135, 3138, 3186, 3213, 
3222, 3225, 3269, 3273, 3288, 3291, 3329, 3363, 3375, 3376, 3397, 3415, 3491, 
3500, 2296, 3547, 129, 1039, 8, 1053, 1441, 2372, 1974, 289, 2449, 2747, 2075, 
57, 3550, 3069, 89, 1603, 1570, 54, 152, 1035, 1456, 506, 1387, 43, 1805, 1851, 
1843, 2587, 1908, 1790, 2630, 901, 13, 529, 705, 81, 2668, 1086, 603, 1986, 
2516, 2969, 2671, 568, 4636, 1115, 864, 381, 4516, 2608, 677, 88, 1825, 3220, 
3284, 947, 1190, 2233, 4489, 3320, 2957, 4146, 1841, 25, 643, 4352, 14, 4261, 
3876, 1311, 1342, 4057, 3974) ORDER BY content.time_create DESC LIMIT 10;

http://explain.depesz.com/s/ccE

As you can see, planner estimates 115 rows, but there are 259554 of them.

This query shows root of the problem
EXPLAIN ANALYZE SELECT content.* FROM content JOIN blog ON blog.id = 
content.blog_id JOIN community_prop ON blog.id = community_prop.blog_id;
 QUERY PLAN 
 
-
 Hash Join  (cost=24498.17..137922.26 rows=2624 width=572) (actual 
time=36.028..1342.267 rows=408374 loops=1)
   Hash Cond: (content.blog_id = blog.id)
   ->  Seq Scan on content  (cost=0.00..102364.99 rows=1260899 width=572) 
(actual time=0.030..983.274 rows=1256128 loops=1)
   ->  Hash  (cost=24439.07..24439.07 rows=4728 width=8) (actual 
time=35.964..35.964 rows=4728 loops=1)
 Buckets: 1024  Batches: 1  Memory Usage: 185kB
 ->  Nested Loop  (cost=0.00..24439.07 rows=4728 width=8) (actual 
time=0.064..33.092 rows=4728 loops=1)
   ->  Seq Scan on community_prop  (cost=0.00..463.28 rows=4728 
width=4) (actual time=0.004..5.089 rows=4728 loops=1)
   ->  Index Scan using blog_pkey on blog  (cost=0.00..5.06 rows=1 
width=4) (actual time=0.005..0.005 rows=1 loops=4728)
 Index Cond: (id = community_prop.blog_id)
 Total runtime: 1361.354 ms

2624 vs 408374

Joining only content with blog: 1260211 vs 1256124.
Joining only blog with community_prop: 4728 vs 4728
Joining only content with community_prop: 78304 vs 408376

SHOW default_statistics_target ;
 default_statistics_target 
---
 500

I already altered stats on blog_id column 
ALTER TABLE content ALTER COLUMN blog_id SET STATISTICS 1000;

Tried setting 3000 and 1 on all join columns - did not make a difference.
Tried setting n_distinct on content(blog_id) manually to different values from 
1 to 20 (exact distinct is 90k, vacuum sets it to 76k) - did not change 
the estimate result set, only estimated index lookup.

Don't now what to do with this.

Ready to provide any additional information.
Thank you for your time.

Re: [GENERAL] [PERFORM] Inaccurate Explain Cost

2012-09-28 Thread Matthias

Am 27.09.2012, 02:04 Uhr, schrieb Jeff Janes :


On Wed, Sep 26, 2012 at 1:21 PM, hubert depesz lubaczewski
 wrote:

On Wed, Sep 26, 2012 at 02:38:09PM -0400, Robert Sosinski wrote:

The first query shows a cost of 190,169.55 and runs in 199,806.951 ms.
When I disable nested loop, I get a cost of 2,535,992.34 which runs in
only 133,447.790 ms.  We have run queries on our database with a cost
of 200K cost before and they ran less then a few seconds, which makes
me wonder if the first query plan is inaccurate.  The other issue is
understanding why a query plan with a much higher cost is taking less
time to run.


Are you under impression that cost should be somehow related to actual
time?


I am certainly under that impression.  If the estimated cost has
nothing to do with run time, then what is it that the cost-based
optimizer is trying to optimize?


See http://www.postgresql.org/docs/9.2/static/runtime-config-query.html  
section "18.7.2. Planner Cost Constants".


-Matthias


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