On Tue, Nov 25, 2008 at 15:56, A. Kretschmer <
[EMAIL PROTECTED]> wrote:

> am  Tue, dem 25.11.2008, um 15:34:57 +0800 mailte Guillaume Bog folgendes:
> > Hi dear Postgres users.
> >
> > I have performance issues if I do the following pseudo-query:
> >
> > SELECT a, b, (SELECT count(*) FROM t2 WHERE something) AS c
> > FROM t1 ORDER BY a LIMIT 10;
> >
> > After some tests, it seems to me that the subquery on t2 is computed for
> all
> > rows of t1. As I don't "ORDER BY c", there is no need to compute c for
> every
> > row. I know I can (or should ?) work with joins or with a subquery in the
> from
> > clause, but I'd like to make sure there is no other way before changing
> my
> > sqls.
>
> Please check your presumption with explain analyse <your query>.
>
> For example:
>
> test=*# explain analyse select t1.*, (select count(1) from t2) from t1
> order by 1 limit 5;
>                                                  QUERY PLAN
>
> --------------------------------------------------------------------------------------------------------------
>  Limit  (cost=186.54..186.55 rows=5 width=4) (actual time=0.087..0.104
> rows=3 loops=1)
>   InitPlan
>     ->  Aggregate  (cost=36.75..36.76 rows=1 width=0) (actual
> time=0.022..0.024 rows=1 loops=1)
>           ->  Seq Scan on t2  (cost=0.00..31.40 rows=2140 width=0) (actual
> time=0.004..0.008 rows=1 loops=1)
>   ->  Sort  (cost=149.78..155.13 rows=2140 width=4) (actual
> time=0.082..0.088 rows=3 loops=1)
>         Sort Key: i
>         ->  Seq Scan on t1  (cost=0.00..31.40 rows=2140 width=4) (actual
> time=0.046..0.056 rows=3 loops=1)
>  Total runtime: 0.197 ms
> (8 rows)
>
>
> Both tables executes only one scan.
>

It seems that you are right. By further testing I found that a WHERE
condition in the subquery was making the query hundred times slower. As I'm
not very familiar with explain analyze, I paste them below. Why do I have
"merge join" and "merge cond" in one case and "subplan" in the other case?
Note that "u_xref_ug_id" is a reference and therefore b-tree indexed.


vf_cn2fr=# EXPLAIN ANALYZE SELECT ug_id AS id, ug_en AS name, ug_type AS
type,
(SELECT count(*) FROM forms_groups JOIN users ON fg_xref_u_id = u_id WHERE
u_xref_ug_id = ug_id) as groupes
 FROM users_groups ORDER BY "ug_type","ug_en" LIMIT 5;

QUERY
PLAN

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=513022.74..513022.76 rows=5 width=26) (actual
time=31172.258..31172.271 rows=5 loops=1)
   ->  Sort  (cost=513022.74..513023.74 rows=397 width=26) (actual
time=31172.255..31172.259 rows=5 loops=1)
         Sort Key: ug_type, ug_en
         ->  Seq Scan on users_groups  (cost=0.00..513005.61 rows=397
width=26) (actual time=83.273..31167.266 rows=397 loops=1)
               SubPlan
                 ->  Aggregate  (cost=1292.18..1292.19 rows=1 width=0)
(actual time=78.498..78.499 rows=1 loops=397)
                       ->  Hash Join  (cost=146.18..1290.52 rows=663
width=0) (actual time=30.023..78.389 rows=102 loops=397)
                             Hash Cond: (forms_groups.fg_xref_u_id =
users.u_id)
                             ->  Seq Scan on forms_groups
(cost=0.00..985.88 rows=40488 width=4) (actual time=0.005..42.046 rows=40490
loops=372)
                             ->  Hash  (cost=137.10..137.10 rows=726
width=4) (actual time=0.306..0.306 rows=112 loops=397)
                                   ->  Index Scan using
users_u_xref_ug_id_idx on users  (cost=0.00..137.10 rows=726 width=4)
(actual time=0.013..0.169 rows=112 loops=397)
                                         Index Cond: (u_xref_ug_id = $0)
 Total runtime: 31172.363 ms
(13 rows)

vf_cn2fr=# EXPLAIN ANALYZE SELECT ug_id AS id, ug_en AS name, ug_type AS
type,
(SELECT count(*) FROM forms_groups JOIN users ON fg_xref_u_id = u_id) as
groupes
 FROM users_groups ORDER BY "ug_type","ug_en" LIMIT 5;

QUERY
PLAN

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=4530.86..4530.87 rows=5 width=26) (actual
time=325.353..325.365 rows=5 loops=1)
   InitPlan
     ->  Aggregate  (cost=4505.74..4505.75 rows=1 width=0) (actual
time=320.673..320.674 rows=1 loops=1)
           ->  Merge Join  (cost=0.00..4404.52 rows=40488 width=0) (actual
time=0.176..281.602 rows=40490 loops=1)
                 Merge Cond: (forms_groups.fg_xref_u_id = users.u_id)
                 ->  Index Scan using forms_groups_fg_xref_u_id_idx on
forms_groups  (cost=0.00..1576.38 rows=40488 width=4) (actual
time=0.020..64.556 rows=40490 loops=1)
                 ->  Index Scan using users_pkey on users
(cost=0.00..2212.00 rows=44313 width=4) (actual time=0.015..73.373
rows=47689 loops=1)
   ->  Sort  (cost=25.11..26.10 rows=397 width=26) (actual
time=325.350..325.355 rows=5 loops=1)
         Sort Key: ug_type, ug_en
         ->  Seq Scan on users_groups  (cost=0.00..7.97 rows=397 width=26)
(actual time=320.693..321.192 rows=397 loops=1)
 Total runtime: 325.457 ms
(11 rows)




>
>
> Andreas
> --
> Andreas Kretschmer
> Kontakt:  Heynitz: 035242/47150,   D1: 0160/7141639 (mehr: -> Header)
> GnuPG-ID:   0x3FFF606C, privat 0x7F4584DA   http://wwwkeys.de.pgp.net
>
> --
> Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-general
>

Reply via email to