Рефакторинг медленно выполняющегося запроса с помощью подзапроса в Postgres - PullRequest
0 голосов
/ 18 октября 2018

У меня запрос, который выполняется слишком долго (600 мс).Это происходит в основном из-за наличия ключевого слова Distinct, без которого оно выполняется за ~ 20 мс.Я пытался убрать Distinct и использовать Group By на visit.participation_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))) 

У меня уже есть индексы на Visit member_id и event_id.

Как это можно изменить, чтобы не использовать операцию Distinct или что еще можно сделать?Будет ли иметь смысл использовать здесь материализованное представление?

1 Ответ

0 голосов
/ 18 октября 2018

Вы можете переписать его с помощью EXISTS:

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