Postgresql 在Postgres中使用子查询重构执行缓慢的查询

Postgresql 在Postgres中使用子查询重构执行缓慢的查询,postgresql,activerecord,query-optimization,Postgresql,Activerecord,Query Optimization,我有一个查询需要花费太长时间才能执行600毫秒。这主要是因为有Distinct关键字,如果没有它,它将在20毫秒内执行。我尝试在访问时取出Distinct并使用Group By。参与id,但我没有看到任何性能改进。以下是原始查询: SELECT COUNT(*) FROM "participations" WHERE "participations"."event_id" = $1 AND "participations"."is_preview" = $2 AND ("participatio

我有一个查询需要花费太长时间才能执行600毫秒。这主要是因为有Distinct关键字,如果没有它,它将在20毫秒内执行。我尝试在访问时取出Distinct并使用Group By。参与id,但我没有看到任何性能改进。以下是原始查询:

SELECT COUNT(*) FROM "participations" WHERE "participations"."event_id" = $1 AND "participations"."is_preview" = $2 AND ("participations"."id" NOT IN (SELECT DISTINCT "visits"."participation_id" FROM "visits" INNER JOIN "ahoy_events" ON "ahoy_events"."visit_id" = "visits"."id" WHERE "visits"."event_id" = $3 AND "visits"."participation_id" IN (SELECT "participations"."id" FROM "participations" WHERE "participations"."event_id" = $4 AND "participations"."is_preview" = $5))) 
我已经有了访问参与者id和事件id的索引

如何将其重构为不使用Distinct操作,或者还能做些什么?在这里使用物化视图有意义吗

您可以使用EXISTS重写它:

不要使用count*,因为它必须遍历所有行,如果event\u id在索引中,请使用countevent\u id,这样会更快。从查询中删除不同的部分不应更改查询的结果?您仅在NOT in子句中使用它,并且一个Id存在1次或多次这一事实不会对结果产生任何影响。
SELECT COUNT(*) 
FROM "participations" p2
WHERE p2."event_id" = $1 
   AND p2."is_preview" = $2 
   AND NOT EXISTS (SELECT 1
                   FROM "visits" 
                   JOIN "ahoy_events" ON "ahoy_events"."visit_id" = "visits"."id" 
                   JOIN  "participations" ON "visits"."participation_id" = "participations"."id"
                   WHERE "visits"."event_id" = $3 
                     AND "participations"."event_id" = $4  
                     AND "participations"."is_preview" = $5
                     AND p2."participation_id" = "participations"."id"))