Add partial index on project_features.id
What does this MR do and why?
Add index on project_features.id
where monitor_access_level
is not zero. The index is needed to optimize a new metric (to be introduced in !109380 (merged))
Contributes to #382972 (closed)
Metric's query
SELECT COUNT("project_features"."id")
FROM "project_features"
WHERE "project_features"."monitor_access_level" != 0 AND "project_features"."id" BETWEEN 1 AND 100000
Index
CREATE INDEX idx_project_features_id_where_monitor_access_level_not_zero
ON project_features USING btree (id) WHERE monitor_access_level <> 0;
-- The query has been executed. Duration: 3.670 min
Before
- https://explain.depesz.com/s/TT7x
- https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/14608/commands/51157
- https://gitlab.slack.com/archives/CLJMDRD8C/p1674056753394329
After
- https://explain.depesz.com/s/BQhw
- https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/14629/commands/51246
- https://gitlab.slack.com/archives/CLJMDRD8C/p1674133393323689
Alternative indexes
I've also tried the following indexes, but it seems to me they didn't perform well
CREATE INDEX idx_project_features_monitor_access_level_and_id
ON project_features USING btree (monitor_access_level, id);
-- The query has been executed. Duration: 3.648 min
- https://explain.depesz.com/s/ss6p
- https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/14629/commands/51242
- https://gitlab.slack.com/archives/CLJMDRD8C/p1674131245382039
CREATE INDEX idx_project_features_monitor_access_level
ON project_features USING btree (monitor_access_level);
-- The query has been executed. Duration: 40.174 s
- https://explain.depesz.com/s/fGwYA
- https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/14629/commands/51244
- https://gitlab.slack.com/archives/CLJMDRD8C/p1674132458267279
rails db:migrate
→ be rails db:migrate
main: == 20230120093325 AddMonitorAccessLevelIndexToProjectFeatures: migrating ======
main: -- transaction_open?()
main: -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main: -> 0.0947s
main: -- index_exists?(:project_features, :id, {:where=>"monitor_access_level <> 0", :name=>"idx_on_project_features_id_where_monitor_access_level_not_zero", :algorithm=>:concurrently})
main: -> 0.0026s
main: -- execute("SET statement_timeout TO 0")
main: -> 0.0002s
main: -- add_index(:project_features, :id, {:where=>"monitor_access_level <> 0", :name=>"idx_on_project_features_id_where_monitor_access_level_not_zero", :algorithm=>:concurrently})
main: -> 0.0038s
main: -- execute("RESET statement_timeout")
main: -> 0.0002s
main: == 20230120093325 AddMonitorAccessLevelIndexToProjectFeatures: migrated (0.1105s)
ci: == 20230120093325 AddMonitorAccessLevelIndexToProjectFeatures: migrating ======
ci: -- transaction_open?()
ci: -> 0.0000s
ci: -- view_exists?(:postgres_partitions)
ci: -> 0.0006s
ci: -- index_exists?(:project_features, :id, {:where=>"monitor_access_level <> 0", :name=>"idx_on_project_features_id_where_monitor_access_level_not_zero", :algorithm=>:concurrently})
ci: -> 0.0030s
ci: -- execute("SET statement_timeout TO 0")
ci: -> 0.0005s
ci: -- add_index(:project_features, :id, {:where=>"monitor_access_level <> 0", :name=>"idx_on_project_features_id_where_monitor_access_level_not_zero", :algorithm=>:concurrently})
ci: -> 0.0044s
ci: -- execute("RESET statement_timeout")
ci: -> 0.0002s
ci: == 20230120093325 AddMonitorAccessLevelIndexToProjectFeatures: migrated (0.0176s)
rails db:rollback:main
→ be rails db:rollback:main
main: == 20230120093325 AddMonitorAccessLevelIndexToProjectFeatures: reverting ======
main: -- transaction_open?()
main: -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main: -> 0.1398s
main: -- indexes(:project_features)
main: -> 0.0034s
main: -- execute("SET statement_timeout TO 0")
main: -> 0.0002s
main: -- remove_index(:project_features, {:algorithm=>:concurrently, :name=>"idx_on_project_features_id_where_monitor_access_level_not_zero"})
main: -> 0.0021s
main: -- execute("RESET statement_timeout")
main: -> 0.0002s
main: == 20230120093325 AddMonitorAccessLevelIndexToProjectFeatures: reverted (0.1556s)
rails db:rollback:ci
→ be rails db:rollback:ci
ci: == 20230120093325 AddMonitorAccessLevelIndexToProjectFeatures: reverting ======
ci: -- transaction_open?()
ci: -> 0.0000s
ci: -- view_exists?(:postgres_partitions)
ci: -> 0.1672s
ci: -- indexes(:project_features)
ci: -> 0.0070s
ci: -- execute("SET statement_timeout TO 0")
ci: -> 0.0003s
ci: -- remove_index(:project_features, {:algorithm=>:concurrently, :name=>"idx_on_project_features_id_where_monitor_access_level_not_zero"})
ci: -> 0.0024s
ci: -- execute("RESET statement_timeout")
ci: -> 0.0003s
ci: == 20230120093325 AddMonitorAccessLevelIndexToProjectFeatures: reverted (0.1990s)
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Edited by Vitali Tatarintev