Commit 11fb7376 authored by Vladimir Shushlin's avatar Vladimir Shushlin

Optimize EnvironmentsByDeploymentsFinder query

When implementing
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72781

We planned to have this subquery:
  AND EXISTS (
    SELECT 1
    FROM "deployments"
    WHERE "deployments"."environment_id" = "environments"."id"
      AND (ref = $4)
  )

But I forgot to that deployments are scoped by project,
and the resulting query is

EXISTS (SELECT "deployments".*
  FROM   "deployments"
  WHERE  "deployments"."project_id" = 50
  AND ( ref = 'main' )
  AND ( environment_id = environments.id )) )

project_id filter forces this query to use
index_deployments_on_project_id_and_ref
instead of index_deployments_on_environment_id_and_ref
which was introduced for this finder

This commit adds unscope(where: :project_id).

Resulting query now is:

SELECT "environments".*
FROM   "environments"
WHERE  "environments"."project_id" = 50
       AND ( "environments"."state" IN ( 'available' ) )
       AND ( EXISTS (SELECT "deployments".*
                     FROM   "deployments"
                     WHERE  ( ref = 'main' )
                            AND ( environment_id = environments.id )) )
ORDER  BY (SELECT Max("deployments"."id")
           FROM   "deployments"
           WHERE  "deployments"."environment_id" = "environments"."id") ASC
          nulls first

It brings execution time from 1.6 minutes to 6 seconds with cold cache.
It's still slow, but much better than it was.
parent a3f02794
......@@ -25,8 +25,9 @@ module Environments
environments =
if Feature.enabled?(:environments_by_deployments_finder_exists_optimization, project, default_enabled: :yaml)
# TODO: replace unscope with deployments = Deployment on top of the method https://gitlab.com/gitlab-org/gitlab/-/issues/343544
project.environments.available
.where('EXISTS (?)', deployments.where('environment_id = environments.id'))
.where('EXISTS (?)', deployments.unscope(where: :project_id).where('environment_id = environments.id'))
else
environment_ids = deployments
.group(:environment_id)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment