Search Postgresql Archives

Optimizer problem in 8.1.6

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux