Commit 1bd3d2fb authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Improve pagination of users in admin panel

When there are a large number of users the pagination query in the admin
panel users list times out.

This commit changes the query to an approximate and paginates without
counts if it is over the limit.

Changelog: performance
parent 568571cf
......@@ -10,12 +10,15 @@ class Admin::UsersController < Admin::ApplicationController
feature_category :users
PAGINATION_WITH_COUNT_LIMIT = 1000
def index
@users = User.filter_items(params[:filter]).order_name_asc
@users = @users.search_with_secondary_emails(params[:search_query]) if params[:search_query].present?
@users = users_with_included_associations(@users)
@users = @users.sort_by_attribute(@sort = params[:sort])
@users = @users.page(params[:page])
@users = @users.without_count if paginate_without_count?
@cohorts = load_cohorts
......@@ -228,6 +231,12 @@ class Admin::UsersController < Admin::ApplicationController
protected
def paginate_without_count?
counts = Gitlab::Database::Count.approximate_counts([User])
counts[User] > PAGINATION_WITH_COUNT_LIMIT
end
def users_with_included_associations(users)
users.includes(:authorized_projects) # rubocop: disable CodeReuse/ActiveRecord
end
......
......@@ -83,6 +83,6 @@
= render partial: 'admin/users/user', collection: @users
= paginate @users, theme: "gitlab"
= paginate_collection @users
= render partial: 'admin/users/modals'
---
title: Improve pagination of users in the admin panel
merge_request: 59884
author:
type: performance
......@@ -34,6 +34,29 @@ RSpec.describe Admin::UsersController do
let(:target_id) { 'i_analytics_cohorts' }
let(:request_params) { { tab: 'cohorts' } }
end
context 'pagination' do
context 'when number of users is over the pagination limit' do
before do
stub_const('Admin::UsersController::PAGINATION_WITH_COUNT_LIMIT', 5)
allow(Gitlab::Database::Count).to receive(:approximate_counts).with([User]).and_return({ User => 6 })
end
it 'marks the relation for pagination without counts' do
get :index
expect(assigns(:users)).to be_a(Kaminari::PaginatableWithoutCount)
end
end
context 'when number of users is below the pagination limit' do
it 'marks the relation for pagination with counts' do
get :index
expect(assigns(:users)).not_to be_a(Kaminari::PaginatableWithoutCount)
end
end
end
end
describe 'GET :id' do
......
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