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