pg.ddx.io  pgsql-performance@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Andy Colson <andy@squeakycode.net>
To: Matt White <mattw922@gmail.com>
To: pgsql-performance@postgresql.org
Subject: Re: Slow-ish Query Needs Some Love
Date: Tue, 02 Feb 2010 14:11:34 -0600
Message-ID: <4B6886F6.4080402@squeakycode.net> (raw)
In-Reply-To: <250b74b4-f38f-4dab-a8bc-91d6d152d46c@h9g2000prn.googlegroups.com>
References: <1d4feebf-ff4d-4463-b1c8-d1a12d27400c@z10g2000prh.googlegroups.com>
	<hk9816$qh5$1@news.eternal-september.org>
	<250b74b4-f38f-4dab-a8bc-91d6d152d46c@h9g2000prn.googlegroups.com>

On 2/2/2010 1:03 PM, Matt White wrote:
> On Feb 2, 6:06 am, Edgardo Portal<egportal2...@yahoo.com>  wrote:
>> On 2010-02-02, Matt White<mattw...@gmail.com>  wrote:
>>
>>> I have a relatively straightforward query that by itself isn't that
>>> slow, but we have to run it up to 40 times on one webpage load, so it
>>> needs to run much faster than it does. Here it is:
>>
>>> SELECT COUNT(*) FROM users, user_groups
>>>   WHERE users.user_group_id = user_groups.id AND NOT users.deleted AND
>>> user_groups.partner_id IN
>>>   (partner_id_1, partner_id_2);
>>
>>> The structure is partners have user groups which have users. In the
>>> test data there are over 200,000 user groups and users but only ~3000
>>> partners. Anyone have any bright ideas on how to speed this query up?
>>
>> Can you avoid running it 40 times, maybe by restructuring the
>> query (or making a view) along the lines of the following and
>> adding some logic to your page?
>>
>> SELECT p.partner_id, ug.user_group_id, u.id, count(*)
>>    FROM partners p
>>         LEFT JOIN user_groups ug
>>                ON ug.partner_id=p.partner_id
>>         LEFT JOIN users u
>>                ON u.user_group_id=ug.id
>>   WHERE NOT u.deleted
>>   GROUP BY 1,2,3
>> ;
>
> Thanks for the suggestion. The view didn't seem to speed things up.
> Perhaps we can reduce the number of times it's called, we'll see. Any
> additional ideas would be helpful. Thanks.

I agree with Edgardo, I think the biggest time saver will be reducing 
trips to the database.

But... do you have an index on users.user_group_id?

Does rewriting it change the plan any?

SELECT COUNT(*) FROM users
inner join user_groups on (users.user_group_id = user_groups.id)
where NOT users.deleted
AND user_groups.partner_id IN (partner_id_1, partner_id_2);


And... it looks like the row guestimate is off a litte:

Index Scan using user_groups_partner_id_idx
on user_groups
(cost=0.00..133.86 rows=3346 width=8)
(actual time=0.049..96.992 rows=100001 loops=2)


It guessed 3,346 rows, but actually got 100,001.  Have you run an 
analyze on it?  If so, maybe bumping up the stats might help?

-Andy



view thread (6+ messages)  latest in thread

Message-ID: <4B6886F6.4080402@squeakycode.net>
Permalink:  ../4B6886F6.4080402@squeakycode.net/
Also on:    postgresql.org/message-id/4B6886F6.4080402@squeakycode.net

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-performance@postgresql.org
  Cc: andy@squeakycode.net, mattw922@gmail.com
  Subject: Re: Slow-ish Query Needs Some Love
  In-Reply-To: <4B6886F6.4080402@squeakycode.net>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox