2010-06-24 6 views
3

J'ai entendu plusieurs fois que postgres gère existe requêtes encore plus vite que gauche rejoindre. http://archives.postgresql.org/pgsql-performance/2002-12/msg00185.phpPostgreSQL: existe vs gauche rejoindre

C'est certainement vrai pour une agrégation de table.

Mais dans notre cas leur est plus d'un et la même requête construire avec existe qui font postgres pour accrocher toujours:

explain 
SELECT count(DISTINCT "groups".id) AS count_all 
FROM "groups" 
WHERE (exists(
    select * from products p where groups.id = p.group_id AND exists(
     select * from products_categories pc where p.id = pc.product_id AND pc.category_id in (2,3))) AND groups.id != 3) 

Résultat:

Aggregate (cost=26413436.66..26413436.67 rows=1 width=4) 
    -> Seq Scan on groups (cost=0.00..26413403.84 rows=13126 width=4) 
     Filter: ((id <> 3) AND (subplan)) 
     SubPlan 
      -> Index Scan using index_products_on_group_id on products p (cost=0.00..1006.13 rows=1 width=1483) 
       Index Cond: ($1 = group_id) 
       Filter: (subplan) 
       SubPlan 
        -> Seq Scan on products_categories pc (cost=0.00..498.49 rows=1 width=8) 
         Filter: ((category_id = ANY ('{2,3}'::integer[])) AND ($0 = product_id)) 

C'est la cause racine d'un temps d'exécution incroyablement long? Est-ce une sorte de problème de configuration?

Merci, Bogdan.

+0

Existe-t-il un index sur groups.id? Parce que pour moi, il semble qu'il n'y en a pas. Aussi, pouvez-vous nous dire ce que vous essayez d'accomplir? Nous pouvons peut-être vous aider à optimiser votre requête pour vous. – EarthMind

Répondre

1

Eh bien, pour chaque ligne de "groupes", postgresql effectue un scan complet de products_categories, ce qui n'est pas bon. Pas nécessairement un problème de configuration, mais peut-être que la requête pourrait être déclarée sans imbrication de sous-requêtes comme ça?

SELECT count(DISTINCT "groups".id) AS count_all 
FROM "groups" 
WHERE exists(
    select 1 from products p where groups.id = p.group_id 
      join products_categories pc on pc.product_id = p.id 
    where pc.category_id in (2,3) 
    ) and groups.id <> 3 

Performante aussi products_categories ont un index sur product_id?