Re: [PERFORM] help speeding up a query in postgres 8.4.5

2011-05-11 Thread Scott Marlowe
On Tue, Apr 5, 2011 at 1:25 PM, Maria L. Wilson
 wrote:

This bit:

> left outer join INVENTORY IV on GV.GRANULE_ID = IV.GRANULE_ID, INVSENSOR
> INVS

has both an explicit and an implicit join.  This can constrain join
re-ordering in the planner.  Can you change it to explicit joins only
and see if that helps?

-- 
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 refusing to use >1 core

2011-05-11 Thread Pierre C



I suspect your app is doing lots of tiny single-row queries instead of
efficiently batching things. It'll be wasting huge amounts of time
waiting for results. Even if every query is individually incredibly
fast, with the number of them you seem to be doing you'll lose a LOT of
time if you loop over lots of little SELECTs.


Using unix sockets, you can expect about 10-20.000 queries/s on small  
simple selects per core, which is quite a feat. TCP adds overhead, so it's  
slower. Over a network, add ping time.


In plpgsql code, you avoid roundtrips, data serializing, and context  
switches, it can be 2-4x faster.


But a big SQL query can process millions of rows/s, it is much more  
efficient.


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


[PERFORM] 'Interesting' prepared statement slowdown on large table join

2011-05-11 Thread Prodan, Andrei

  Hello everyone,

  I have the following scenario:
  There's a web service that updates some information in two tables,
every 5 minutes.
  In order to do this it will issue a select on the tables, get some
data, think about it, and then update it if necessary.

  Sometimes - about once every two weeks, I think, it will start using
an extremely inefficient plan where it will loop on many results from
the large table instead of getting the few results from small table and
looping on those. 
  The difference in performance is devastating - from 18 ms to 10-20
seconds, and of course drags everything down.
  The situation will usually not resolve itself - but it will resolve
after i run "ANALYZE party; ANALYZE big_table" about... 3-5 times.
Interesting.

  When the problem is occuring, it is completely reproducible using
local psql - thus probably not a connector issue.
  I have tried to reconnect and to re-prepare the statement to allow it
to choose a new plan after the 'first' analyze, but it didn't help.
  I have tried to increase ANALYZE statistics target on party_id (as the
join field) on both tables to 300, but it doesn't appear to help (not
even with the frequency of incidents).


The select is as follows:
prepare ps(varchar,varchar,varchar) as select party.party_id from party,
big_table where external_id = $1 and party.party_id = big_table.party_id
and attr_name = $2 and attr_value = $3;
PREPARE
execute ps('13','GroupId','testshop');
party_id
--
 659178

The query will always return exactly one row.

I hope this is enough information to start a discussion on how to avoid
this. The only reliable solution we've come up with so far is to split
selects and do the join in Java, but this seems like a very unorthodox
solution and could cause other trouble down the road. 

Thank you in advance,
Andrei Prodan
Systems Administator


testdb=# select count(1) from party where external_id='13';
count
---
 4
(1 row)
testdb=# select count(1) from big_table where attr_name='GroupId';
  count
-
 1025867
(1 row)

testdb=# select count(1) from big_table where attr_value='testshop';
 count

 917704
(1 row)

Table party:
Rows: 1.8M
Table size: 163 MB
Indexes size: 465 MB

Table big_table: 
- Frequently updated
Rows: 7.2M
Table size: 672 MB
Indexes size: 1731 MB

GOOD PLAN:
testdb=# explain analyze execute ps('13','GroupId','testshop');
QUERY
PLAN


-
--
 Nested Loop  (cost=0.00..19.11 rows=1 width=7) (actual
time=2.662..18.388 rows=1 loops=1)
   ->  Index Scan using partyext_id_idx on party  (cost=0.00..8.47
rows=1 width=7) (actual time=2.439
..2.495 rows=4 loops=1)
 Index Cond: ((external_id)::text = ($1)::text)
   ->  Index Scan using pk_big_table on big_table  (cost=0.00..10.62
rows=1 width=7) (act ual time=3.972..3.972 rows=0 loops=4)
 Index Cond: (((big_table.party_id)::text =
(party.party_id)::text) AND ((party_attribu te.attr_name)::text =
($2)::text))
 Filter: ((big_table.attr_value)::text = ($3)::text)  Total
runtime: 18.484 ms
(7 rows)

BAD PLAN:
testdb=# explain analyze execute ps('13','GroupId','testshop');
  QUERY
PLAN

---
Nested Loop  (cost=0.00..56.83 rows=4 width=7) (actual
time=355.569..9989.681 rows=1 loops=1)
   ->  Index Scan using attr_name_value on big_table  (cost=0.00..22.85
rows=4 width=7) (actual time=0.176..757.646 rows=914786 loops=1)
 Index Cond: (((attr_name)::text = ($2)::text) AND
((attr_value)::text = ($3)::text))
   ->  Index Scan using pk_party on party  (cost=0.00..8.48 rows=1
width=7) (actual time=0.010..0.010 rows=0 loops=914786)
 Index Cond: ((party.party_id)::text =
(big_table.party_id)::text)
 Filter: ((party.external_id)::text = ($1)::text) Total runtime:
9989.749 ms
(7 rows)


  name   |
current_setting
-+--

-
 version | PostgreSQL 8.4.4 on
x86_64-unknown-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20080704 (Red
Hat 4.1.2-48), 64-bit
 autovacuum_analyze_scale_factor | 0.05
 autovacuum_max_workers  | 9
 autovacuum_vacuum_scale_factor  | 0.1
 checkpoint_segments | 30
 effective_cache_size| 6GB
 effective_io_concurrency| 6
 lc_collate  | en_US.UTF-8
 lc_ctype| en_US.UTF-8
 listen_addresses| *
 log_autovacuum_min_duration | 1s
 log_checkpoints | on
 log_destination | stderr
 log_directo

Re: [PERFORM] Postgres NoSQL emulation

2011-05-11 Thread Pierre C



why even  have multiple rows? just jam it all it there! :-D


LOL

But seriously, when using an ORM to stuff an object hierarchy into a  
database, you usually get problems with class inheritance, and all  
solutions suck more or less (ie, you get a zillion tables, with assorted  
pile of JOINs, or stinky key/attributes schemes where all attributes end  
up as TEXT, or a table with 200 columns, most of them being NULL for a  
given line).


NoSQL guys say "hey just use NoSQL !".

In a (common) case where the classes have some fields in common and othen  
searched, and that the DB needs to know about and access easily, those  
become columns, with indexes. Then the other fields which only occur in  
some derived class and are not very interesting to the DB get shoved into  
a hstore. The big bonus being that you use only one table, and the "extra"  
fields can still be accessed and indexed (but a little slower than a  
normal column). However I believe hstore can only store TEXT values...


Could be interesting. Or not.

--
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] partition query on multiple cores

2011-05-11 Thread Mason S
On Tue, May 10, 2011 at 12:22 PM, Shaun Thomas  wrote:

> On 05/10/2011 10:06 AM, Maciek Sakrejda wrote:
>
>  I have 8-core server, I wanted to ask whether a query can be divided for
>>> multiple processors or cores, if it could be what to do in postgresql
>>>
>>
>> No, at this time (and for the foreseeable future), a single query will
>> run on a single core.
>>
>
> It can *kinda* be done. Take a look at GridSQL. It's really good for
> splitting up reporting-like queries that benefit from parallel access of
> large tables. It's not exactly Hadoop, but I ran a test on a single system
> with two separate instances of PostgreSQL, and a single query over those two
> nodes cut execution time in half.
>
> It's meant for server parallelism, so I wouldn't necessarily recommend
> splitting your data up across nodes on the same server. But it seems to
> deliver as promised when used in the right circumstances.
>
>


Yes, GridSQL is useful even in multi-core scenarios on a single server for
query parallelism. You can also use the same PostgreSQL instance (cluster),
as the virtual node databases are named distinctly, which simplifies
configuration.


Mason


Re: [PERFORM] help speeding up a query in postgres 8.4.5

2011-05-11 Thread Robert Haas
On Tue, May 10, 2011 at 2:20 PM, Maria L. Wilson
 wrote:
> haven't tested a composite index
>
> invsensor is 2,003,980 rows and 219MB
> granver is 5,138,730 rows and 556MB
> the machine has 32G memory
> seq_page_cost, random_page_costs & effective_cache_size are set to the
> defaults (1,4, and 128MB) - looks like they could be bumped up.
> Got any recommendations?

Yeah, I'd try setting effective_cache_size=24GB, seq_page_cost=0.1,
random_page_cost=0.1 and see if you get a better plan.  If possible,
can you post the EXPLAIN ANALYZE output with those settings for us?

If that doesn't cause the planner to use the indexes, then I'd be
suspicious that there is something wrong with those indexes that makes
the planner think it *can't* use them.  It would be helpful to see the
EXPLAIN output after SET enable_seqscan=off.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

-- 
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] partition query on multiple cores

2011-05-11 Thread Mason S
On Tue, May 10, 2011 at 2:57 PM, Tomas Vondra  wrote:

> Dne 10.5.2011 18:22, Shaun Thomas napsal(a):
> > On 05/10/2011 10:06 AM, Maciek Sakrejda wrote:
> >
> >>> I have 8-core server, I wanted to ask whether a query can be divided
> for
> >>> multiple processors or cores, if it could be what to do in postgresql
> >>
> >> No, at this time (and for the foreseeable future), a single query will
> >> run on a single core.
> >
> > It can *kinda* be done. Take a look at GridSQL.
>
> Or pgpool-II, that can give you something similar.
>
> http://pgpool.projects.postgresql.org/
>
>
Last time I tested parallelism in pgpool-II, I saw that if your query is
fairly simple, pgpool-II will help. If it is more complex with joins and
aggregates, GridSQL will typically outperform it. GridSQL pushes down joins
as much as possible, minimizes row shipping, and parallelizes aggregates and
grouping.


Mason Sharp


Re: [PERFORM] help speeding up a query in postgres 8.4.5

2011-05-11 Thread Tom Lane
Scott Marlowe  writes:
> On Tue, Apr 5, 2011 at 1:25 PM, Maria L. Wilson
>  wrote:
> This bit:

>> left outer join INVENTORY IV on GV.GRANULE_ID = IV.GRANULE_ID, INVSENSOR
>> INVS

> has both an explicit and an implicit join.  This can constrain join
> re-ordering in the planner.  Can you change it to explicit joins only
> and see if that helps?

Since there's a WHERE constraint on IV, the outer join is going to be
strength-reduced to an inner join (note the lack of any outer joins in
the plan).  So that isn't going to matter.

AFAICS this is just plain an expensive query.  The two filter
constraints are not very selective, each passing more than a million
rows up to the join.  You can't expect to join millions of rows in no
time flat.  About all you can do is try to bump up work_mem enough that
the join won't use temp files --- for something like this, that's likely
to require a setting of hundreds of MB.  I'm not sure whether Maria is
using a version in which EXPLAIN ANALYZE will show whether a hash join
was batched, but that's what I'd be looking at.

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] 'Interesting' prepared statement slowdown on large table join

2011-05-11 Thread Shaun Thomas

On 05/11/2011 06:08 AM, Prodan, Andrei wrote:


Index Scan using attr_name_value on big_table  (cost=0.00..22.85
rows=4 width=7) (actual time=0.176..757.646 rows=914786 loops=1)


Holy inaccurate statistics, Batman!

Try increasing your statistics target for attr_name and attr_value in 
your big table. I know you said you set it to 300 on party_id, but what 
happened here is that the optimizer thought this particular name/value 
combo in your big table would return less rows, and it was horribly, 
horribly wrong.


You might think about bumping up your default_statistics_target anyway 
to prevent problems like this in general. But definitely increase it on 
those two columns and reanalyze. My guess is that your big_table is big 
enough that each analyze gets a different random sample of the various 
attr_name and attr_value combinations, so occasionally it'll get too few 
and start badly skewing query plans.


--
Shaun Thomas
OptionsHouse | 141 W. Jackson Blvd. | Suite 800 | Chicago IL, 60604
312-676-8870
stho...@peak6.com

__

See  http://www.peak6.com/email_disclaimer.php
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] Postgres refusing to use >1 core

2011-05-11 Thread Shaun Thomas

On 05/10/2011 11:26 PM, Scott Marlowe wrote:


I.e. don't grab 1,000 rows and work on them on the client side and
then insert data, do the data mangling in the query in the database.
My experience has been that moving things like this into the database
can result in performance gains of several factors, taking hour long
processes and making them run in minutes.


This is a problem I encounter constantly wherever I go. Programmer 
selects millions of rows from giant table. Programmer loops through 
results one by one doing some magic on them. Programmer submits queries 
back to the database. Even in batches, that's going to take ages.


Databases are beasts at set-based operations. If the programmer can 
build a temp table of any kind and load that, they can turn their 
update/insert/whatever into a simple JOIN that runs several orders of 
magnitude faster. Going the route of parallelism will probably work too, 
but I doubt it's the right solution in this case.


When there are tables with millions of rows involved, processing 111 per 
second is a bug. Even with ten perfectly balanced threads, 30 hours only 
becomes three. On decent hardware, you can probably drop, reload, and 
index the entire table faster than that.


--
Shaun Thomas
OptionsHouse | 141 W. Jackson Blvd. | Suite 800 | Chicago IL, 60604
312-676-8870
stho...@peak6.com

__

See  http://www.peak6.com/email_disclaimer.php
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] 'Interesting' prepared statement slowdown on large table join

2011-05-11 Thread Tom Lane
Shaun Thomas  writes:
> On 05/11/2011 06:08 AM, Prodan, Andrei wrote:
>> Index Scan using attr_name_value on big_table  (cost=0.00..22.85
>> rows=4 width=7) (actual time=0.176..757.646 rows=914786 loops=1)

> Holy inaccurate statistics, Batman!

> Try increasing your statistics target for attr_name and attr_value in 
> your big table.

Actually, the big problem here is probably not lack of statistics, but
the insistence on using a parameterized prepared plan in the first
place.  If you're going to be doing queries where the number of selected
rows varies that much, using a generic parameterized plan is just a
recipe for shooting yourself in the foot.  The planner cannot know what
the actual search values will be, and thus has no way of adapting the
plan based on how common those search values are.  Having more stats
won't help in that situation.

Forget the prepared plan and just issue the query the old-fashioned way.

I do suspect that the reason the plan is flipping back and forth is
instability of the collected statistics, which might be improved by
increasing the stats target, or then again maybe not.  But that's really
rather irrelevant.

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] Poor performance when joining against inherited tables

2011-05-11 Thread Robert Haas
On Mon, Apr 11, 2011 at 4:11 PM, Lucas Madar  wrote:
> I have a database that contains many tables, each with some common
> characteristics. For legacy reasons, they have to be implemented in a way so
> that they are *all* searchable by an older identifier to find the newer
> identifier. To do this, we've used table inheritance.
>
> Each entry has an id, as well as a legacyid1 and legacyid2. There's a master
> table that the application uses, containing a base representation and common
> characteristics:
>
> objects ( id, ... )
> item ( id, legacyid1, legacyid2 )
>  | - itemXX
>  | - itemYY
>
> There is nothing at all in the item table, it's just used for inheritance.
> However, weird things happen when this table is joined:
>
> EXPLAIN ANALYZE SELECT * FROM objects INNER JOIN item f USING ( id );
>
>  QUERY PLAN
> 
>  Hash Join  (cost=457943.85..1185186.17 rows=8643757 width=506)
>   Hash Cond: (f.id = objects.id)
>   ->  Append  (cost=0.00..224458.57 rows=8643757 width=20)
>         ->  Seq Scan on item f  (cost=0.00..26.30 rows=1630 width=20)
>         ->  Seq Scan on itemXX f  (cost=0.00..1.90 rows=90 width=20)
>         ->  Seq Scan on itemYY f  (cost=0.00..7.66 rows=266 width=20)
>         ->  Seq Scan on itemZZ f  (cost=0.00..1.02 rows=2 width=20)
>         ...
>   ->  Hash  (cost=158447.49..158447.49 rows=3941949 width=490)
>         ->  Seq Scan on objects  (cost=0.00..158447.49 rows=3941949
> width=490)
>
> This scans everything over everything, and obviously takes forever (there
> are millions of rows in the objects table, and tens of thousands in each
> itemXX table).
>
> However, if I disable seqscan (set enable_seqscan=false), I get the
> following plan:
>
>  QUERY PLAN
> 
>  Hash Join  (cost=10001298843.53..290002337961.71 rows=8643757 width=506)
>   Hash Cond: (f.id = objects.id)
>   ->  Append  (cost=100.00..29536334.43 rows=8643757 width=20)
>         ->  Seq Scan on item f  (cost=100.00..126.30
> rows=1630 width=20)
>         ->  Index Scan using xxx_pkey on itemXX f  (cost=0.00..10.60 rows=90
> width=20)
>         ->  Index Scan using yyy_pkey on itemYY f  (cost=0.00..25.24
> rows=266 width=20)
>         ->  Index Scan using zzz_pkey on itemZZ f  (cost=0.00..9.28 rows=2
> width=20)
>         ...
>   ->  Hash  (cost=999347.17..999347.17 rows=3941949 width=490)
>         ->  Index Scan using objects_pkey on objects (cost=0.00..999347.17
> rows=3941949 width=490)
>
> This seems like a much more sensible query plan.

I don't think so.  Scanning the index to extract all the rows in a
table is typically going to be a lot slower than a sequential scan.

A more interesting question is why you're not getting a plan like this:

Nested Loop
-> Seq Scan on objects
-> Append
   ->  Index Scan using xxx_pkey on itemXX
   ->  Index Scan using yyy_pkey on itemYY
   ->  Index Scan using zzz_pkey on itemZZ

> But it seems to think doing
> a sequential scan on the *empty* item table is excessively expensive in this
> case.
>
> Aside from enable_seqscan=false, is there any way I can make the query
> planner not balk over doing a seqscan on an empty table?

Why would you care?  A sequential scan of an empty table is very fast.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

-- 
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] Poor performance when joining against inherited tables

2011-05-11 Thread Tom Lane
Robert Haas  writes:
> A more interesting question is why you're not getting a plan like this:

> Nested Loop
> -> Seq Scan on objects
> -> Append
>->  Index Scan using xxx_pkey on itemXX
>->  Index Scan using yyy_pkey on itemYY
>->  Index Scan using zzz_pkey on itemZZ

Probably because there are 4 million rows in the objects table.

Or maybe it's a pre-8.2 database and can't even generate such a plan.
But if it did generate it, it would almost certainly have decided that
this was more expensive than a hash or merge join.

People have this weird idea that the existence of an index ought to make
enormous joins free ...

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] Postgres refusing to use >1 core

2011-05-11 Thread Pierre C


This is a problem I encounter constantly wherever I go. Programmer  
selects millions of rows from giant table. Programmer loops through  
results one by one doing some magic on them. Programmer submits queries  
back to the database. Even in batches, that's going to take ages.


Reminds me of a recent question on stackoverflow :

http://stackoverflow.com/questions/5952020/how-to-optimize-painfully-slow-mysql-query-that-finds-correlations

And the answer :

http://stackoverflow.com/questions/5952020/how-to-optimize-painfully-slow-mysql-query-that-finds-correlations/5954041#5954041

OP was thinking "row-based", with subqueries in the role of "doing some  
magicm".
Using a set-based solution with cascading WITH CTEs (and using the  
previous CTE as a source in the next one for aggregation) => 100x speedup !


--
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] 'Interesting' prepared statement slowdown on large table join

2011-05-11 Thread Jeff Janes
On Wed, May 11, 2011 at 4:08 AM, Prodan, Andrei
 wrote:
>
...
>
>
> The select is as follows:
> prepare ps(varchar,varchar,varchar) as select party.party_id from party,
> big_table where external_id = $1 and party.party_id = big_table.party_id
> and attr_name = $2 and attr_value = $3;
> PREPARE
> execute ps('13','GroupId','testshop');

>
> BAD PLAN:
> testdb=# explain analyze execute ps('13','GroupId','testshop');
>                                                                  QUERY
...
>   ->  Index Scan using attr_name_value on big_table  (cost=0.00..22.85
> rows=4 width=7) (actual time=0.176..757.646 rows=914786 loops=1)
>         Index Cond: (((attr_name)::text = ($2)::text) AND
> ((attr_value)::text = ($3)::text))

So it expects 4 rows and finds 914786, essentially the whole table.
So that is bad.  But what is it thinking during the GOOD PLAN state?

A possible way to get that information is to prepare a simpler
prepared statement that omits the join to party and explain analyze it
with the same params for attr_name and attr_value.  If that gives you
the full table scan rather than index scan, then you can "set
enable_seqscan=off" try to force the index scan.

Cheers,

Jeff

-- 
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 refusing to use >1 core

2011-05-11 Thread gnuoytr
 Original message 
>Date: Wed, 11 May 2011 11:04:49 -0500
>From: pgsql-performance-ow...@postgresql.org (on behalf of Shaun Thomas 
>)
>Subject: Re: [PERFORM] Postgres refusing to use >1 core  
>To: Scott Marlowe 
>Cc: Craig Ringer ,Aren Cambre 
>,
>
>On 05/10/2011 11:26 PM, Scott Marlowe wrote:
>
>> I.e. don't grab 1,000 rows and work on them on the client side and
>> then insert data, do the data mangling in the query in the database.
>> My experience has been that moving things like this into the database
>> can result in performance gains of several factors, taking hour long
>> processes and making them run in minutes.
>
>This is a problem I encounter constantly wherever I go. Programmer 
>selects millions of rows from giant table. Programmer loops through 
>results one by one doing some magic on them. Programmer submits queries 
>back to the database. Even in batches, that's going to take ages.
>
>Databases are beasts at set-based operations. If the programmer can 
>build a temp table of any kind and load that, they can turn their 
>update/insert/whatever into a simple JOIN that runs several orders of 
>magnitude faster. Going the route of parallelism will probably work too, 
>but I doubt it's the right solution in this case.
>
>When there are tables with millions of rows involved, processing 111 per 
>second is a bug. Even with ten perfectly balanced threads, 30 hours only 
>becomes three. On decent hardware, you can probably drop, reload, and 
>index the entire table faster than that.
>
>-- 
>Shaun Thomas
>OptionsHouse | 141 W. Jackson Blvd. | Suite 800 | Chicago IL, 60604
>312-676-8870
>stho...@peak6.com
>
>__
>
>See  http://www.peak6.com/email_disclaimer.php
>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

So, the $64 question:  how did you find an engagement where, to bend 
Shakespeare, "first thing we do, is kill all the coders" isn't required?  This 
RBAR mentality, abetted by xml/NoSql/xBase, is utterly pervasive.  They 
absolutely refuse to learn anything different from the COBOL/VSAM messes of 
their grandfathers; well modulo syntax, of course.  The mere suggestion, in my 
experience, that doing things faster with fewer lines of code/statements in the 
engine is met with overt hostility.

Regards,
Robert

-- 
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 refusing to use >1 core

2011-05-11 Thread Scott Marlowe
On Wed, May 11, 2011 at 1:53 PM,   wrote:

> So, the $64 question:  how did you find an engagement where, to bend 
> Shakespeare, "first thing we do, is kill all the coders" isn't required?  
> This RBAR mentality, abetted by xml/NoSql/xBase, is utterly pervasive.  They 
> absolutely refuse to learn anything different from the COBOL/VSAM messes of 
> their grandfathers; well modulo syntax, of course.  The mere suggestion, in 
> my experience, that doing things faster with fewer lines of code/statements 
> in the engine is met with overt hostility.

It really depends.  For a lot of development scaling to large numbers
of users is never needed, and it's often more economical to develop
quickly with a less efficient database layer.  In my last job all our
main development was against a large transactional / relational db.
But some quick and dirty internal development used some very
inefficient MVC methods but it only had to handle 45 users at a time,
max, and that was 45 users who accessed the system a few minutes at a
time.

I've seen EVA systems that people tried to scale that were handling
thousands of queries a second that when converted to real relational
dbs needed dozens of queries a second to run, required a fraction of
db horsepower, and could scale to the same number of users with only
1/10th to 1/100th the database underneath it.  In those instances, you
only have to show the much higher efficiency to the people who pay for
the database servers.

-- 
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 refusing to use >1 core

2011-05-11 Thread Shaun Thomas

On 05/11/2011 02:53 PM, gnuo...@rcn.com wrote:


So, the $64 question:  how did you find an engagement where, to bend
Shakespeare, "first thing we do, is kill all the coders" isn't
required?


It's just one of those things you have to explain. Not just how to fix 
it, but *why* doing so fixes it. It's also not really a fair expectation 
in a lot of ways. Even when a coder uses all SQL, their inexperience in 
the engine can still ruin performance. We spend years getting to know 
PostgreSQL, or just general DB techniques. They do the same with coding. 
And unless they're a developer for a very graphics intensive project, 
they're probably not well acquainted with set theory.


Just today, I took a query like this:

  UPDATE customer c
 SET c.login_counter = a.counter
FROM (SELECT session_id, count(*) as counter
FROM session
   WHERE date_created >= CURRENT_DATE
   GROUP BY session_id) a
   WHERE c.process_date = CURRENT_DATE
 AND c.customer_id = a.session_id

And suggested this instead:

  CREATE TEMP TABLE tmp_login_counts AS
  SELECT session_id, count(1) AS counter
FROM auth_token_arc
   WHERE date_created >= CURRENT_DATE
   GROUP BY session_id

  UPDATE reporting.customer c
 SET login_counter = a.counter
FROM tmp_login_counts a
   WHERE c.process_date = CURRENT_DATE
 AND c.customer_id = a.session_id

The original query, with our very large tables, ran for over *two hours* 
thanks to a nested loop iterating over the subquery. My replacement ran 
in roughly 30 seconds. If we were using a newer version of PG, we could 
have used a CTE. But do you get what I mean? Temp tables are a fairly 
common technique, but how would a coder know about CTEs? They're pretty 
new, even to *us*.


We hold regular Lunch'n'Learns for our developers to teach them the 
good/bad of what they're doing, and that helps significantly. Even hours 
later, I see them using the techniques I showed them. The one I'm 
presenting soon is entitled '10 Ways to Ruin Performance' and they're 
all specific examples taken from day-to-day queries and jobs here, all 
from different categories of mistake. It's just a part of being a good DBA.


--
Shaun Thomas
OptionsHouse | 141 W. Jackson Blvd. | Suite 800 | Chicago IL, 60604
312-676-8870
stho...@peak6.com

__

See  http://www.peak6.com/email_disclaimer.php
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] Postgres refusing to use >1 core

2011-05-11 Thread gnuoytr
 Original message 
>Date: Wed, 11 May 2011 17:04:50 -0500
>From: pgsql-performance-ow...@postgresql.org (on behalf of Shaun Thomas 
>)
>Subject: Re: [PERFORM] Postgres refusing to use >1 core  
>To: 
>Cc: Scott Marlowe ,Craig Ringer 
>,Aren Cambre 
>,
>
>On 05/11/2011 02:53 PM, gnuo...@rcn.com wrote:
>
>> So, the $64 question:  how did you find an engagement where, to bend
>> Shakespeare, "first thing we do, is kill all the coders" isn't
>> required?
>
>It's just one of those things you have to explain. Not just how to fix 
>it, but *why* doing so fixes it. It's also not really a fair expectation 
>in a lot of ways. Even when a coder uses all SQL, their inexperience in 
>the engine can still ruin performance. We spend years getting to know 
>PostgreSQL, or just general DB techniques. They do the same with coding. 
>And unless they're a developer for a very graphics intensive project, 
>they're probably not well acquainted with set theory.
>
>Just today, I took a query like this:
>
>   UPDATE customer c
>  SET c.login_counter = a.counter
> FROM (SELECT session_id, count(*) as counter
> FROM session
>WHERE date_created >= CURRENT_DATE
>GROUP BY session_id) a
>WHERE c.process_date = CURRENT_DATE
>  AND c.customer_id = a.session_id
>
>And suggested this instead:
>
>   CREATE TEMP TABLE tmp_login_counts AS
>   SELECT session_id, count(1) AS counter
> FROM auth_token_arc
>WHERE date_created >= CURRENT_DATE
>GROUP BY session_id
>
>   UPDATE reporting.customer c
>  SET login_counter = a.counter
> FROM tmp_login_counts a
>WHERE c.process_date = CURRENT_DATE
>  AND c.customer_id = a.session_id
>
>The original query, with our very large tables, ran for over *two hours* 
>thanks to a nested loop iterating over the subquery. My replacement ran 
>in roughly 30 seconds. If we were using a newer version of PG, we could 
>have used a CTE. But do you get what I mean? Temp tables are a fairly 
>common technique, but how would a coder know about CTEs? They're pretty 
>new, even to *us*.
>
>We hold regular Lunch'n'Learns for our developers to teach them the 
>good/bad of what they're doing, and that helps significantly. Even hours 
>later, I see them using the techniques I showed them. The one I'm 
>presenting soon is entitled '10 Ways to Ruin Performance' and they're 
>all specific examples taken from day-to-day queries and jobs here, all 
>from different categories of mistake. It's just a part of being a good DBA.
>
>-- 
>Shaun Thomas
>OptionsHouse | 141 W. Jackson Blvd. | Suite 800 | Chicago IL, 60604
>312-676-8870
>stho...@peak6.com
>
>__
>
>See  http://www.peak6.com/email_disclaimer.php
>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

You're (both) fortunate to have Suits and colleagues who are open to doing this 
A Better Way.  Bless you.

Regards,
Robert

-- 
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 refusing to use >1 core

2011-05-11 Thread Josh Berkus
On 5/11/11 3:04 PM, Shaun Thomas wrote:
> The original query, with our very large tables, ran for over *two hours*
> thanks to a nested loop iterating over the subquery. My replacement ran
> in roughly 30 seconds. If we were using a newer version of PG, we could
> have used a CTE. But do you get what I mean? Temp tables are a fairly
> common technique, but how would a coder know about CTEs? They're pretty
> new, even to *us*.

For that matter, it would be even better if PostgreSQL realized that a
materialize of the subquery was a better execution plan, and just did it
for you.

-- 
Josh Berkus
PostgreSQL Experts Inc.
http://pgexperts.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] Postgres refusing to use >1 core

2011-05-11 Thread Aren Cambre
>
> I suspect your app is doing lots of tiny single-row queries instead of
> efficiently batching things. It'll be wasting huge amounts of time
> waiting for results. Even if every query is individually incredibly
> fast, with the number of them you seem to be doing you'll lose a LOT of
> time if you loop over lots of little SELECTs.
>

So here's what's going on.

I have a table of about 12,000,000 traffic tickets written by the Texas
Department of Public Safety (TxDPS). Each ticket has a route name and a
reference marker. On Interstate highways, reference marker = mile post. On
all other roads, from US highways down to Farm to Market roads, the
reference marker is based on a grid superimposed over the state. Basically
that reference marker increments as the road crosses a grid line, so unless
the road is perfectly N-S or E-W, these reference markers are more than a
mile apart.

I have a separate table with data from the Texas Department of
Transportation (TxDOT). It is a database of almost all the state's reference
markers, along with latitude and longitude for each.

I am trying to geolocate each ticket by correlating the ticket's
route/reference marker to the same in the TxDOT database. And it's not
straightforward for a few reasons:

*1. TxDPS and TxDOT formats are different.*

TxDPS uses 1-5 to denote route type. 1 = Interstate. 2 = US or any state
highway except Farm to Market. 3 = Farm to Market, 4 = county road, 5 =
local road. So if the route name is 0071 and route type is 2, it could mean
US 71 or TX 71, both of which really exist in Texas but are on different
parts of the state.

I haven't proven it yet, but it is possible that no two routes of the same
number are in the same county. You wouldn't find both TX 71 and US 71 in the
same county.

For now, I am looking up the TxDOT database based on route type, name, and
county, and I may need to repeat the lookup until I get a match.

In the above example, if the ticket is written for route_name = 0071,
route_type = 2, and county = 206, then I need to do searches against the
TxDOT database for:

   1. rte_nm = 'US71' AND county_num='206'
   2. rte_nm = 'SH71' AND county_num='206'
   3. rte_nm = 'UA71' AND county_num='206'
   4. rte_nm = 'UP71' AND county_num='206'
   5. ...

*2. Not TxDPS reference markers correspond to TxDOT reference markers.*

Now, if I've matched a route, I have to find the reference marker.

The TxDOT database is pretty good but not 100% complete, so some TxDPS
tickets' reference markers may not exist in the TxDOT table. Plus, it's
possible that some TxDPS tickets have the wrong marker.

To compensate, I am looking for the closest reference marker along the route
that is not more than 50 marker units away, either direction. I've again
implemented that with multiple queries, where I don't stop until I find a
match. Suppose I am searching for reference marker 256 on TX 71. The queries
will be like this:

   1. rte_nm = 'SH71' AND rm = '256' (base marker)
   2. rte_nm = 'SH71' AND rm = '257' (+1)
   3. rte_nm = 'SH71' AND rm = '255' (-1)
   4. rte_nm = 'SH71' AND rm = '258' (+2)
   5. rte_nm = 'SH71' AND rm = '254' (-2)
   6. ...
   7. rte_nm = 'SH71' AND rm = '306' (+50)
   8. rte_nm = 'SH71' AND rm = '206' (-50)

Assuming a matching route name was found in the prior step, the app will
have 1 to 101 of these queries for each ticket.

Assuming steps 1 and 2 above worked out, now I have a reference marker. So I
write to a third table that has four columns:

   1. *HA_Arrest_Key* (varchar(18) that refers back to the TxDPS tickets
   table
   2. *gid* (integer that refers to the unique identity of the reference
   marker in the TxDOT table)
   3. *distance* (integer that is the distance, in reference markers,
   between that noted in the TxDPS ticket and the nearest marker found in the
   TxDOT table)
   4. *hasLatLong* (Boolean that is true if TxDPS also recorded latitude and
   longitude for the ticket, presumably from an in-car device. These don't
   appear to be that accurate, plus a substantial portion of tickets have no
   lat/long.)

Right now, I am doing a separate INSERT for each of the 12,000,000 rows
inserted into this table.

I guess the app is chatty like you suggest? HOWEVER, if I am reading system
activity correctly, the master thread that is going through the 12,000,000
tickets appears to have its own Postgres process, and based on how quickly
RAM usage initially shoots up the first ~60 seconds or so the app runs, it
may be reading all these rows into memory. But I am consulting with Npgsql
developers separately to make sure I am really understanding correctly. They
suspect that the PLINQ stuff (basically "multithreading in a can") may not
be dispatching threads as expected because it may be misreading things.

By using a producer/consumer model like that you can ensure that thread
> 1 is always talking to the database, keeping Pg busy, and thread 2 is
> always working the CPUs.


Thanks for the example and illustrati

Re: [PERFORM] Postgres refusing to use >1 core

2011-05-11 Thread Aren Cambre
>
> > Using one thread, the app can do about 111 rows per second, and it's
> > only exercising 1.5 of 8 CPU cores while doing this. 12,000,000 rows /
> > 111 rows per second ~= 30 hours.
>
> I don't know how I missed that. You ARE maxing out one cpu core, so
> you're quite right that you need more threads unless you can make your
> single worker more efficient.
>

And the problem is my app already has between 20 and 30 threads. Something
about C#'s PLINQ may not be working as intended...

Aren


Re: [PERFORM] Postgres refusing to use >1 core

2011-05-11 Thread Aren Cambre
>
>
>  I suspect your app is doing lots of tiny single-row queries instead of
>> efficiently batching things. It'll be wasting huge amounts of time
>> waiting for results. Even if every query is individually incredibly
>> fast, with the number of them you seem to be doing you'll lose a LOT of
>> time if you loop over lots of little SELECTs.
>>
>
> Using unix sockets, you can expect about 10-20.000 queries/s on small
> simple selects per core, which is quite a feat. TCP adds overhead, so it's
> slower. Over a network, add ping time.
>

I'm talking to a Postgres on localhost, so in theory, I ought to be getting
really good throughput, but again, the problem may be with the way C#'s
PLINQ "multithreading in a can" is managing things.

Aren


Re: [PERFORM] HashJoin order, hash the large or small table? Postgres likes to hash the big one, why?

2011-05-11 Thread Robert Haas
On Wed, Apr 13, 2011 at 1:22 PM, Scott Carey  wrote:
> A pathological skew case (all relations with the same key), should be
> _cheaper_ to probe.   There should be only _one_ entry in the hash (for
> the one key), and that entry will be a list of all relations matching the
> key.  Therefore, hash probes will either instantly fail to match on an
> empty bucket, fail to match the one key with one compare, or match the one
> key and join on the matching list.
>
> In particular for anti-join, high skew should be the best case scenario.

I think this argument may hold some water for an anti-join, and maybe
for a semi-join, but it sure doesn't seem right for any kind of join
that has to iterate over all matches (rather than just the first one);
that is, inner, left, right, or full.

> A hash structure that allows multiple entries per key is inappropriate for
> skewed data, because it is not O(n).  One that has one entry per key
> remains O(n) for all skew.  Furthermore, the hash buckets and # of entries
> is proportional to n_distinct in this case, and smaller and more cache and
> memory friendly to probe.

I don't think this argument is right.  The hash table is sized for a
load factor significantly less than one, so if there are multiple
entries in a bucket, it is fairly likely that they are all for the
same key.  Granted, we have to double-check the keys to figure that
out; but I believe that the data structure you are proposing would
require similar comparisons.  The only difference is that they'd be
required when building the hash table, rather than when probing it.

> You can put either relation on the outside with an anti-join, but would
> need a different algorithm and cost estimator if done the other way
> around.  Construct a hash on the join key, that keeps a list of relations
> per key, iterate over the other relation, and remove the key and
> corresponding list from the hash when there is a match, when complete the
> remaining items in the hash are the result of the join (also already
> grouped by the key).  It could be terminated early if all entries are
> removed.
> This would be useful if the hash was small, the other side of the hash too
> large to fit in memory, and alternative was a massive sort on the other
> relation.

This would be a nice extension of commit
f4e4b3274317d9ce30de7e7e5b04dece7c4e1791.

> Does the hash cost estimator bias towards smaller hashes due to hash probe
> cost increasing with hash size due to processor caching effects?  Its not
> quite O(n) due to caching effects.

I don't think we account for that (and I'm not convinced we need to).

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

-- 
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] DBT-5 & Postgres 9.0.3

2011-05-11 Thread Robert Haas
On Tue, Apr 12, 2011 at 3:51 AM, Sethu Prasad  wrote:
> Anyone lucky to have dbt5 run for PostgreSQL 9.0.3?!
>
> I am trying on Novell SuSE Linux Enterprise Server 11 SP1 x86_64 with a
> virtual machine and bit hard with no success run yet. If you can help me
> with any docs will be more of a support.

What's going wrong for you?

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

-- 
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 refusing to use >1 core

2011-05-11 Thread Scott Marlowe
On Wed, May 11, 2011 at 9:20 PM, Aren Cambre  wrote:
>> Using unix sockets, you can expect about 10-20.000 queries/s on small
>> simple selects per core, which is quite a feat. TCP adds overhead, so it's
>> slower. Over a network, add ping time.
>
> I'm talking to a Postgres on localhost, so in theory, I ought to be getting
> really good throughput, but again, the problem may be with the way C#'s
> PLINQ "multithreading in a can" is managing things.

local tcp is gonna be slower not faster than unix sockets, not faster.
 But the big issue is that you need to exlpore doing the work in a
large set not iteratively.  Operations on sets are often much faster
in aggregate.

-- 
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] Checkpoint execution overrun impact?

2011-05-11 Thread Robert Haas
On Fri, Apr 22, 2011 at 5:21 AM, drvillo  wrote:
> -given the configuration attached (which is basically a vanilla one) and the
> number of buffers written at each execution, are these execution times
> normal or above average?

They seem fine.  Remember that the write is deliberately spread out;
it's not as if the system couldn't write out 130-160 8k blocks in less
than 30 s.

> -in the case of the execution that overruns past the timeout, what are the
> implications wrt the client application?

Not sure what you are referring to here.

> -AFAIU client connections are basically stalled during checkpoints. Is it
> reasonable to infer that the fact that the application blocking on a
> getConnection() might be related to checkpoints being executed?
> -considering some tuning on the PG side, should I try increasing
> checkpoint_timeout and rising checkpoint_completion_target to lessen the
> impact of IO on the client or should I shorten the period so there's less
> stuff to write? from the number of buffers written on average I'd assume the
> first option is the one to go for but I might miss some bit of reasoning
> here...

I'm a bit puzzled by all of this because the logs you posted seem to
reflect a system under very light load.  Each checkpoint is writing no
more than 4% of shared_buffers and the sync phases are generally
completing in less than one second.  I don't see why that would be
causing stalls.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

-- 
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] tuning on ec2

2011-05-11 Thread Robert Haas
On Tue, Apr 26, 2011 at 11:15 AM, Joel Reymont  wrote:
> I'm running pgsql on an m1.large EC2 instance with 7.5gb available memory.
>
> The free command shows 7gb of free+cached. My understand from the docs is 
> that I should dedicate 1.75gb to shared_buffers (25%) and set 
> effective_cache_size to 7gb.

Sounds like a reasonable starting point.  You could certainly fiddle
around a bit - especially with shared_buffers - to see if some other
setting works better, but that should be in the ballpark.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

-- 
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 refusing to use >1 core

2011-05-11 Thread David Boreham

On 5/11/2011 9:17 PM, Aren Cambre wrote:


So here's what's going on.




If I were doing this, considering the small size of the data set, I'd 
read all the data into memory.
Process it entirely in memory (with threads to saturate all the 
processors you have).

Then write the results to the DB.



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