Class: Gitlab::Pagination::Offset::PaginationWithIndexOnlyScan
- Inherits:
-
Object
- Object
- Gitlab::Pagination::Offset::PaginationWithIndexOnlyScan
- Defined in:
- lib/gitlab/pagination/offset/pagination_with_index_only_scan.rb
Overview
rubocop: disable CodeReuse/ActiveRecord – Generic code for pagination
This class can build optimized offset queries where we try to force the DB to use index-only-scan for skipping the OFFSET rows by selecting the columns in the ORDER BY clause explicitly. The selected rows will be fully loaded from the table using a LATERAL SELECT.
The class can be used with any ActiveRecord scope however, the optimization will be only applied when:
-
‘ORDER BY` clause is present
-
The columns in an ‘ORDER BY` point to one distinct record -> the `ORDER BY` clause can be keyset paginated
Usage:
scope = Issue.where(project_id: 1).order(:id)
records = PaginationWithIndexOnlyScan.new(scope: scope, page: 5, per_page: 100).paginate_with_kaminari puts records.to_a puts records.total_count
Constant Summary collapse
- CTE_NAME =
:index_only_scan_pagination_cte- SUBQUERY_NAME =
:index_only_scan_subquery
Instance Method Summary collapse
-
#initialize(scope:, page:, per_page:) ⇒ PaginationWithIndexOnlyScan
constructor
A new instance of PaginationWithIndexOnlyScan.
- #paginate_with_kaminari ⇒ Object
Constructor Details
#initialize(scope:, page:, per_page:) ⇒ PaginationWithIndexOnlyScan
Returns a new instance of PaginationWithIndexOnlyScan.
27 28 29 30 31 32 33 |
# File 'lib/gitlab/pagination/offset/pagination_with_index_only_scan.rb', line 27 def initialize(scope:, page:, per_page:) @scope = scope @page = page @per_page = per_page @model = scope.model @original_order_values = scope.order_values end |
Instance Method Details
#paginate_with_kaminari ⇒ Object
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/gitlab/pagination/offset/pagination_with_index_only_scan.rb', line 35 def paginate_with_kaminari original_kaminari_query = scope.page(page).per(per_page) # Check for keyset pagination support if keyset_aware_scope && (keyset_order_by_columns.size == original_order_by_columns.size) original_kaminari_query.extend(build_module_for_load) end original_kaminari_query end |