Skip to content

Use efficient in operator query for fetching group & project activities

Abdul Wadood requested to merge 355831-optimize-groups-activity into master

Use efficient in-operator queries to fetch projects and groups activities. Async indexes are required because the events table is too big.

A limit of @limit + @offset has been added to each of the UNION queries generated for the group activity:

SELECT "events".*
FROM ((SELECT * FROM events WHERE project_id IN () LIMIT 20) UNION (SELECT * FROM events WHERE group_id IN ()) LIMIT 20)) events
ORDER BY "events"."id" DESC
LIMIT 20 OFFSET 0

For group activity with no filter, we fetch @limit + @limit events for projects and groups each, sort them in memory and return the recent @limit (=20) events. In the worst case (fetching page 10), we would be sorting around 400 events but it's good for this iteration.

We've already been using the in-operator optimization. It's just that we lacked index and LIMIT for the group activity tab without a filter. This change will make that tab work regardless of the introduced FF. We had to use the multiple IN operator optimizations for the remaining tabs and the performance won't improve without the introduced FF.

Database

Example queries with plan

FF disabled

Activity type Filter Before After
Group - https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9811/commands/34813 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9999/commands/35437
Group Push https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35009 Omitted (expected to time out)
Group Merge https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/34997 Omitted (expected to time out)
Group Issue https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35008 Expected to time out https://explain-depesz.postgres.ai/s/4Z
Group Epic https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35005 https://explain-depesz.postgres.ai/s/Hi
Group Comment https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35018 Omitted (expected to time out)
Group Wiki https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35013 Expected to time out https://explain-depesz.postgres.ai/s/G9
Group Design https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35012 Omitted (expected to time out)
Group Team https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9811/commands/34833 Expected to time out https://explain-depesz.postgres.ai/s/Mh

The project activity queries remain the same with FF disabled and the queries with filter are expected to time out so I have omitted them here.

FF enabled

Activity type Filter Before After
Group - https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9811/commands/34813 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35052
Group Push https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35009 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/10037/commands/35608
Group Merge https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/34997 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/10037/commands/35610
Group Issue https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35008 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/10037/commands/35616
Group Epic https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35005 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/10037/commands/35611
Group Comment https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35018 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35045
Group Wiki https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35013 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35048
Group Design https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35012 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/10037/commands/35615
Group Team https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9811/commands/34833 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/10037/commands/35613
Project - https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9811/commands/34800 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9811/commands/34828
Project Push https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/34988 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35025
Project Merge https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/34990 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35028
Project Issue https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/34991 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35029
Project Comment https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/34992 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35030
Project Wiki https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35000 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35031
Project Design https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/34995 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9919/commands/35032
Project Team https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9811/commands/34802 https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/9811/commands/34825

Migrations

Up:

== 20220422121443 AddAsyncIndexForGroupActivityEvents: migrating ==============
-- index_exists?(:events, [:group_id, :target_type, :action, :id], {:name=>"index_events_for_group_activity", :where=>"group_id IS NOT NULL", :algorithm=>:concurrently})
   -> 0.0081s
== 20220422121443 AddAsyncIndexForGroupActivityEvents: migrated (0.0123s) =====

== 20220425111114 AddAsyncIndexForProjectActivityEvents: migrating ============
-- index_exists?(:events, [:project_id, :target_type, :action, :id], {:name=>"index_events_for_project_activity", :algorithm=>:concurrently})
   -> 0.0077s
== 20220425111114 AddAsyncIndexForProjectActivityEvents: migrated (0.0103s) ===

== 20220425111453 AddAsyncIndexToEventsOnGroupIdAndId: migrating ==============
-- index_exists?(:events, [:group_id, :id], {:name=>"index_events_on_group_id_and_id", :where=>"group_id IS NOT NULL", :algorithm=>:concurrently})
   -> 0.0101s
== 20220425111453 AddAsyncIndexToEventsOnGroupIdAndId: migrated (0.0124s) =====

Down:

== 20220425111453 AddAsyncIndexToEventsOnGroupIdAndId: reverting ==============
== 20220425111453 AddAsyncIndexToEventsOnGroupIdAndId: reverted (0.0129s) =====

== 20220425111114 AddAsyncIndexForProjectActivityEvents: reverting ============
== 20220425111114 AddAsyncIndexForProjectActivityEvents: reverted (0.0013s) ===

== 20220422121443 AddAsyncIndexForGroupActivityEvents: reverting ==============
== 20220422121443 AddAsyncIndexForGroupActivityEvents: reverted (0.0011s) =====

Related to #355831 (closed)

Edited by Abdul Wadood

Merge request reports