Offset vs Cursor Pagination
up vote
2
down vote
favorite
I am trying to compare any performance gain(s) from moving a current offset-based pagination endpoint to a cursor based one.
I have the following ruby code:
@limit = 25
@max_pages = 200
def query
@q ||= MyDataBaseClass.where(status: "open").order(:id)
end
def offset_paginatiion
# count is currently an implementation for this appraoch
total = query.count
ctr = 0
page_size = 1
while page_size < @max_pages
query.limit(@limit).offset(ctr).load
ctr += @limit
page_size += 1
end
end
def keyset_pagination
current_page = query.limit(@limit)
page_size = 1
while true
break if page_size >= @max_pages
page_size += 1
last_id = current_page.last.id
current_page = query.where("id > ?", last_id).limit(@limit).load
end
end
require 'benchmark/ips'
Benchmark.ips do |x|
x.report("offset_pagination") { offset_paginatiion }
x.report("keyset_pagination") { keyset_pagination }
x.compare!
end
I've seeded the database with 1 million rows but you can see here I'm only trying to page up to 200 pages (or 5,000 results).
The two methods are returning the exact same data in the same order so they are functionally equivalent and after running the benchmark are performing nearly the same:
│Calculating -------------------------------------
│ offset_pagination 0.009 (± 0.0%) i/s - 1.000 in 110.100327s
│ keyset_pagination 0.009 (± 0.0%) i/s - 1.000 in 112.732942s
│
│Comparison:
│ offset_pagination: 0.0 i/s
│ keyset_pagination: 0.0 i/s - 1.02x slower
I was under the impression performance (from numerous articles) was a benefit to moving to cursor pagination but have yet to been able to reproduce - what am I doing worng?
performance ruby api postgresql pagination
add a comment |
up vote
2
down vote
favorite
I am trying to compare any performance gain(s) from moving a current offset-based pagination endpoint to a cursor based one.
I have the following ruby code:
@limit = 25
@max_pages = 200
def query
@q ||= MyDataBaseClass.where(status: "open").order(:id)
end
def offset_paginatiion
# count is currently an implementation for this appraoch
total = query.count
ctr = 0
page_size = 1
while page_size < @max_pages
query.limit(@limit).offset(ctr).load
ctr += @limit
page_size += 1
end
end
def keyset_pagination
current_page = query.limit(@limit)
page_size = 1
while true
break if page_size >= @max_pages
page_size += 1
last_id = current_page.last.id
current_page = query.where("id > ?", last_id).limit(@limit).load
end
end
require 'benchmark/ips'
Benchmark.ips do |x|
x.report("offset_pagination") { offset_paginatiion }
x.report("keyset_pagination") { keyset_pagination }
x.compare!
end
I've seeded the database with 1 million rows but you can see here I'm only trying to page up to 200 pages (or 5,000 results).
The two methods are returning the exact same data in the same order so they are functionally equivalent and after running the benchmark are performing nearly the same:
│Calculating -------------------------------------
│ offset_pagination 0.009 (± 0.0%) i/s - 1.000 in 110.100327s
│ keyset_pagination 0.009 (± 0.0%) i/s - 1.000 in 112.732942s
│
│Comparison:
│ offset_pagination: 0.0 i/s
│ keyset_pagination: 0.0 i/s - 1.02x slower
I was under the impression performance (from numerous articles) was a benefit to moving to cursor pagination but have yet to been able to reproduce - what am I doing worng?
performance ruby api postgresql pagination
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I am trying to compare any performance gain(s) from moving a current offset-based pagination endpoint to a cursor based one.
I have the following ruby code:
@limit = 25
@max_pages = 200
def query
@q ||= MyDataBaseClass.where(status: "open").order(:id)
end
def offset_paginatiion
# count is currently an implementation for this appraoch
total = query.count
ctr = 0
page_size = 1
while page_size < @max_pages
query.limit(@limit).offset(ctr).load
ctr += @limit
page_size += 1
end
end
def keyset_pagination
current_page = query.limit(@limit)
page_size = 1
while true
break if page_size >= @max_pages
page_size += 1
last_id = current_page.last.id
current_page = query.where("id > ?", last_id).limit(@limit).load
end
end
require 'benchmark/ips'
Benchmark.ips do |x|
x.report("offset_pagination") { offset_paginatiion }
x.report("keyset_pagination") { keyset_pagination }
x.compare!
end
I've seeded the database with 1 million rows but you can see here I'm only trying to page up to 200 pages (or 5,000 results).
The two methods are returning the exact same data in the same order so they are functionally equivalent and after running the benchmark are performing nearly the same:
│Calculating -------------------------------------
│ offset_pagination 0.009 (± 0.0%) i/s - 1.000 in 110.100327s
│ keyset_pagination 0.009 (± 0.0%) i/s - 1.000 in 112.732942s
│
│Comparison:
│ offset_pagination: 0.0 i/s
│ keyset_pagination: 0.0 i/s - 1.02x slower
I was under the impression performance (from numerous articles) was a benefit to moving to cursor pagination but have yet to been able to reproduce - what am I doing worng?
performance ruby api postgresql pagination
I am trying to compare any performance gain(s) from moving a current offset-based pagination endpoint to a cursor based one.
I have the following ruby code:
@limit = 25
@max_pages = 200
def query
@q ||= MyDataBaseClass.where(status: "open").order(:id)
end
def offset_paginatiion
# count is currently an implementation for this appraoch
total = query.count
ctr = 0
page_size = 1
while page_size < @max_pages
query.limit(@limit).offset(ctr).load
ctr += @limit
page_size += 1
end
end
def keyset_pagination
current_page = query.limit(@limit)
page_size = 1
while true
break if page_size >= @max_pages
page_size += 1
last_id = current_page.last.id
current_page = query.where("id > ?", last_id).limit(@limit).load
end
end
require 'benchmark/ips'
Benchmark.ips do |x|
x.report("offset_pagination") { offset_paginatiion }
x.report("keyset_pagination") { keyset_pagination }
x.compare!
end
I've seeded the database with 1 million rows but you can see here I'm only trying to page up to 200 pages (or 5,000 results).
The two methods are returning the exact same data in the same order so they are functionally equivalent and after running the benchmark are performing nearly the same:
│Calculating -------------------------------------
│ offset_pagination 0.009 (± 0.0%) i/s - 1.000 in 110.100327s
│ keyset_pagination 0.009 (± 0.0%) i/s - 1.000 in 112.732942s
│
│Comparison:
│ offset_pagination: 0.0 i/s
│ keyset_pagination: 0.0 i/s - 1.02x slower
I was under the impression performance (from numerous articles) was a benefit to moving to cursor pagination but have yet to been able to reproduce - what am I doing worng?
performance ruby api postgresql pagination
performance ruby api postgresql pagination
edited Nov 29 at 21:39
asked Nov 29 at 21:24
Anthony
279212
279212
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
I'm not surprised at your results, bar a few minor details that any decent database will optimize away your implementations are the same. You are also basically just re-implementing the find_each method.
Note, you might find a real difference if you used database cursors but that is a completely different thing.
The real difference between the two is that cursor based pagination responds better when the underlying data changes. i.e. using offset based pagination you might have a record included twice or skipped if a record is inserted or deleted by another process.
Looks like your answer got cut off at the end
– 404
Dec 1 at 13:14
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
I'm not surprised at your results, bar a few minor details that any decent database will optimize away your implementations are the same. You are also basically just re-implementing the find_each method.
Note, you might find a real difference if you used database cursors but that is a completely different thing.
The real difference between the two is that cursor based pagination responds better when the underlying data changes. i.e. using offset based pagination you might have a record included twice or skipped if a record is inserted or deleted by another process.
Looks like your answer got cut off at the end
– 404
Dec 1 at 13:14
add a comment |
up vote
0
down vote
I'm not surprised at your results, bar a few minor details that any decent database will optimize away your implementations are the same. You are also basically just re-implementing the find_each method.
Note, you might find a real difference if you used database cursors but that is a completely different thing.
The real difference between the two is that cursor based pagination responds better when the underlying data changes. i.e. using offset based pagination you might have a record included twice or skipped if a record is inserted or deleted by another process.
Looks like your answer got cut off at the end
– 404
Dec 1 at 13:14
add a comment |
up vote
0
down vote
up vote
0
down vote
I'm not surprised at your results, bar a few minor details that any decent database will optimize away your implementations are the same. You are also basically just re-implementing the find_each method.
Note, you might find a real difference if you used database cursors but that is a completely different thing.
The real difference between the two is that cursor based pagination responds better when the underlying data changes. i.e. using offset based pagination you might have a record included twice or skipped if a record is inserted or deleted by another process.
I'm not surprised at your results, bar a few minor details that any decent database will optimize away your implementations are the same. You are also basically just re-implementing the find_each method.
Note, you might find a real difference if you used database cursors but that is a completely different thing.
The real difference between the two is that cursor based pagination responds better when the underlying data changes. i.e. using offset based pagination you might have a record included twice or skipped if a record is inserted or deleted by another process.
edited Dec 2 at 7:59
answered Nov 30 at 9:12
Marc Rohloff
2,98736
2,98736
Looks like your answer got cut off at the end
– 404
Dec 1 at 13:14
add a comment |
Looks like your answer got cut off at the end
– 404
Dec 1 at 13:14
Looks like your answer got cut off at the end
– 404
Dec 1 at 13:14
Looks like your answer got cut off at the end
– 404
Dec 1 at 13:14
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208720%2foffset-vs-cursor-pagination%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown