Optimizer problem in 8.1.6

From: Fernando Schapachnik <fernando(at)mecon(dot)gov(dot)ar>
To: pgsql-general(at)postgresql(dot)org
Subject: Optimizer problem in 8.1.6
Date: 2007-06-22 15:16:07
Message-ID: 20070622151607.GK5964@bal740r0.mecon.gov.ar
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Maybe this is already solved in more advanced releases, but just in
case.

VIEW active_users:
SELECT * FROM users WHERE active AND ((field IS NULL) OR (NOT field));

Table users has index on text field login.

EXPLAIN SELECT * from active_users where login='xxx';
QUERY PLAN
----------------------------------------------------------------------------------
Index Scan using active_users on users u (cost=0.00..5.97 rows=1
width=131)
Index Cond: ("login" = 'xxx'::text)
Filter: (active AND ((field1 IS NULL) OR (NOT field1)))

So far, everything OK.

Now, combined (sorry for the convoluted query, it is build
automatically by an app).

EXPLAIN SELECT DISTINCT p.id
FROM partes_tecnicos p,
rel_usr_sector_parte_tecnico r, active_users u
WHERE ((r.id_parte_tecnico=p.id AND r.id_usr=u.id AND
u.login='xxx' AND r.id_sector=p.id_sector_actual AND
p.id_cola_por_ambito=1)
OR p.id_cola_por_ambito=1)
AND p.id_situacion!=6;

-----
Unique (cost=1016.84..22057814.97 rows=219 width=4)
-> Nested Loop (cost=1016.84..19607287.64 rows=980210931 width=4)
-> Nested Loop (cost=8.07..2060.25 rows=100959 width=4)
-> Index Scan using partes_tecnicos_pkey on
partes_tecnicos p (cost=0.00..33.00 rows=219 width=4)
Filter: ((id_cola_por_ambito = 1) AND
(id_situacion <> 6))
-> Materialize (cost=8.07..12.68 rows=461 width=0)
-> Seq Scan on rel_usr_sector_parte_tecnico r
(cost=0.00..7.61 rows=461 width=0)
-> Materialize (cost=1008.77..1105.86 rows=9709 width=0)
-> Seq Scan on users u (cost=0.00..999.06
rows=9709 width=0)
Filter: (active AND ((field1 IS NULL) OR
(NOT field1)))

Notice the seq. scan on users.

It is solved using:

EXPLAIN SELECT DISTINCT p.id
FROM partes_tecnicos p, pt.rel_usr_sector_parte_tecnico r,
(SELECT id FROM active_users WHERE
login='xxx') u
WHERE ((r.id_parte_tecnico=p.id AND r.id_usr=u.id
AND r.id_sector=p.id_sector_actual AND p.id_cola_por_ambito=1)
OR p.id_cola_por_ambito=1
) AND p.id_situacion!=6;

-------------------------------------------------------------------------------------------------------------
Unique (cost=18.65..2323.23 rows=219 width=4)
-> Nested Loop (cost=18.65..2070.83 rows=100959 width=4)
-> Index Scan using partes_tecnicos_pkey on partes_tecnicos
p (cost=0.00..33.00 rows=219 width=4)
Filter: ((id_cola_por_ambito = 1) AND (id_situacion <>
6))
-> Materialize (cost=18.65..23.26 rows=461 width=0)
-> Nested Loop (cost=0.00..18.19 rows=461 width=0)
-> Index Scan using active_users on users u
(cost=0.00..5.97 rows=1 width=0)
Index Cond: ("login" = 'xxx'::text)
Filter: (active AND ((field1 IS NULL)
OR (NOT field1)))
-> Seq Scan on rel_usr_sector_parte_tecnico r
(cost=0.00..7.61 rows=461 width=0)
(10 rows)

Thanks!

Fernando.

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Jean-David Beyer 2007-06-22 15:35:34 Embedded C++ with ecpg?
Previous Message Joshua D. Drake 2007-06-22 15:11:33 Re: Proposed Feature