2010-06-24 5 views
3

Я слышал много раз, что ручки postgres существует запросов еще быстрее, чем left join. http://archives.postgresql.org/pgsql-performance/2002-12/msg00185.phpPostgreSQL: существует против левого соединения

Это определенно верно для одной агрегации таблиц.

Но в нашем случае их больше, то один и тот же запрос построить с существует, которые делают Postgres висеть вечно:

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) 

результат:

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)) 

Это является основной причиной невероятно долгого времени исполнения? Это какая-то проблема с конфигурацией?

Thanks, Bogdan.

+0

Есть ли указатель на groups.id? Потому что для меня это похоже, что нет. Кроме того, можете ли вы сказать нам, чего вы пытаетесь достичь? Возможно, мы сможем помочь вам оптимизировать ваш запрос для вас. – EarthMind

ответ

1

Ну, для каждой строки в «группах» postgresql выполняет полную проверку products_categories, что не очень хорошо. Не обязательно проблема конфигурации, но, возможно, запрос может быть указан без вложенных подзапросов?

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 

Также имеет products_categories есть индекс по product_id?

Смежные вопросы