Re: Query optimisation and sorting on external merge

From: nha <lyondif02(at)free(dot)fr>
To: Jake Stride <jake(at)omelett(dot)es>
Cc: PgSQL-general <pgsql-general(at)postgresql(dot)org>
Subject: Re: Query optimisation and sorting on external merge
Date: 2009-07-29 12:27:29
Message-ID: 4A704031.60305@free.fr
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Hello,

Le 29/07/09 13:46, Jake Stride a écrit :
> Hi,
>
> I'm trying to optimise a query at the moment, I've added some new
> indexes to stop seq scans, but I'm now trying to work out if I can
> stop a join using external sort to speed up the query. I've included
> an explain analyze below and would appreciate any pointers to gaps in
> my understanding.
>
> explain analyze SELECT p.usercompanyid, 'people' AS type, p.id,
> (p.firstname::text || ' '::text) || p.surname::text AS name,
> p.assigned_to, p.owner, p.organisation_id, phr.username, p.private
> FROM people p
> LEFT JOIN organisation_roles pr ON p.organisation_id =
> pr.organisation_id AND pr.read
> LEFT JOIN hasrole phr ON pr.roleid = phr.roleid;
> [...]

A first idea could be to explicitely join tables organisation_roles and
hasrole before joining with table people. The two first tables are
assumed to be of very small size compared to the (main) table people.
Joining both them as a preliminary step would reduce the number of rows
to join to the latter and thence make the table people scan faster.

A second idea may be to move the clause "pr.read" into a subquery
(sub-select) of table organisation_roles because this latter is the only
table concerned with this clause. Thus, in spite of (hash- or
index-based) scanning the whole table organisation_roles, a smaller part
would be relevant.

Combining these two ideas, a corresponding rewritten query would be as
follows:

SELECT
p.usercompanyid, 'people' AS type, p.id,
(p.firstname::text || ' '::text) || p.surname::text AS name,
p.assigned_to, p.owner, p.organisation_id, phr.username, p.private
FROM people p
LEFT JOIN (
(SELECT pr2.roleid, pr2.organisation_id FROM organisation_roles pr2
WHERE pr2.read) pr
LEFT JOIN hasrole phr ON pr.roleid = phr.roleid
) t
ON p.organisation_id = t.organisation_id;

Let you consider if the corresponding query plan looks better.

Regards.

--
nha / Lyon / France.

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Jake Stride 2009-07-29 12:37:53 Re: Query optimisation and sorting on external merge
Previous Message A. Kretschmer 2009-07-29 11:57:22 Re: Query optimisation and sorting on external merge