Consider removing issue/merge request previous/next buttons
When viewing an individual merge request or issue there are two buttons rendered in the sidebar: "Prev" and "Next". These buttons can be used to navigate to the previous/next issue/merge request, unrelated to their labels or whatsoever (it's purely based on the previous/next iid
values). Per button a query is executed to check if there is a previous/next issue/merge request, if not the button can't be clicked.
There are a few problems with these buttons:
- They ignore any labels whatsoever, meaning that if you filter issues, click one, then click "Next" you may end up at a completely different issue (e.g. one without the label you were filtering by).
- When hovering over the button there's absolutely no info as to what issue/merge request you're going to (e.g. there's no title in the tooltip).
- Both buttons require a single query at least
The biggest problem here is running the queries to render the buttons. At peak in the past 3 hours we had 220 requests per minute to Projects::IssuesController#show
. In the worst case every request required 2 queries (to render both buttons) resulting in 440 queries being executed per minute. Add Projects::MergeRequestsController#show
with peaks up to 100 requests per minute and we have another 200 extra queries in the worst case. Of course not all these requests happen at the exact same time, but it should give an indication of the query impact these two otherwise innocent looking buttons have.
The queries these buttons executed look like this:
SELECT "issues".*
FROM "issues"
WHERE "issues"."deleted_at" IS NULL
AND "issues"."project_id" = 13083
AND ("issues"."state" IN ('opened','reopened'))
AND (iid < 18024)
ORDER BY "issues"."id" ASC
LIMIT 1;
On GitLab.com this produces the following query plan:
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.00..74.07 rows=1 width=1155) (actual time=19.540..19.540 rows=1 loops=1)
-> Index Scan using issues_pkey on issues (cost=0.00..417747.20 rows=5640 width=1155) (actual time=19.538..19.538 rows=1 loops=1)
Filter: ((deleted_at IS NULL) AND ((state)::text = ANY ('{opened,reopened}'::text[])) AND (iid < 18024) AND (project_id = 13083))
Rows Removed by Filter: 31048
Total runtime: 19.574 ms
While the plan itself is not that bad it does still take around 20 milliseconds. Double this (for both buttons) and 40 milliseconds is spent in just checking if we can render two buttons.
The timings of these queries themselves are not the biggest problem. The real problem is that these two buttons in their current state are not useful enough (at least from my point of view) to warrant a potential of 2 extra queries per issue/merge request page. Since there's no meaningful caching strategy that we can use here (how would we expire the cache for example?) and this only gives us more troubles I propose we simply remove these buttons.