Slide 1

Slide 1 text

0 Offset / Cursor Paginationについて 2024-04-12 第86回NearMe技術勉強会 Kaito Asahi

Slide 2

Slide 2 text

1 Cursor Paginationについて ● ページングを実行する方法の1つ ● 他の方法として主なものは、Offset Pagination ○ 詳しくは後ほど紹介 ○ これと比較しながら見てみる

Slide 3

Slide 3 text

2 あれ、そもそもPaginationって何? ● 食べログ:ページ番号をしてページング https://tabelog.com/

Slide 4

Slide 4 text

3 あれ、そもそもPaginationって何? ● Google検索:無限スクロールライク

Slide 5

Slide 5 text

4 あれ、そもそもPaginationって何? ● X(旧Twitter):無限スクロールタイムライン https://twitter.com/

Slide 6

Slide 6 text

5 Why Pagination!? ● クエリにとって重要なこと

Slide 7

Slide 7 text

6 Why Pagination!? ● クエリにとって重要なこと 必要なものだけとろう

Slide 8

Slide 8 text

7 Why Pagination!? ● 検索の取得量が大きくなることは、システム停止などの重大なインシデントを 引き起こす!!(これはフィルタの重要性とも言えるが...) TBS NEWS DIG:https://newsdig.tbs.co.jp/articles/-/924207?display=1

Slide 9

Slide 9 text

8

Slide 10

Slide 10 text

9 Paginationのそれぞれの特徴 ● Offset Pagination ○ 重要な要素 ■ Offset:位置ずらし(skipするデータを考慮してずらす) ○ 特徴 ■ Offsetを用いて、検索済みのものをスキップして再度検索 ■ 次のページがあるかどうかはlimit+1件取得で判定可能 Ex ) 3件ずつ取得するとき(1回目の取得) 1 2 3 4 5 6 取得(次ではskipされる)

Slide 11

Slide 11 text

10 Paginationのそれぞれの特徴 ● Offset Pagination ○ 重要な要素 ■ Offset:位置ずらし(skipするデータを考慮してずらす) ○ 特徴 ■ Offsetを用いて、検索済みのものをスキップして再度検索 ■ 次のページがあるかどうかはlimit+1件取得で判定可能 Ex ) 3件ずつ取得するとき(2回目の取得) 1 2 3 4 5 6 取得(次ではskipされる) skip = 3 Offset

Slide 12

Slide 12 text

11 Paginationのそれぞれの特徴 ● Cursor Pagination ○ 重要な要素 ■ Cursor : データのある点を指す(Cursor部分はスキップする) ○ 特徴 ■ オフセットではなく、ある基準(Cursor)のみをポイント ■ 次のページがあるかどうかはlimit+1件取得で判定可能 Ex ) 3件ずつ取得するとき(検索したら、Cursorを定める) 1 2 3 4 5 6 Cursor 取得

Slide 13

Slide 13 text

12 Paginationのそれぞれの特徴 ● Cursor Pagination ○ 重要な要素 ■ Cursor : データのある点を指す(Cursor部分はスキップする) ○ 特徴 ■ オフセットではなく、ある基準(Cursor)のみをポイント ■ 次のページがあるかどうかはlimit+1件取得で判定可能 Ex ) 3件ずつ取得するとき(Cursorより右の3件を取得!) 1 2 3 4 5 6 Cursor 取得

Slide 14

Slide 14 text

13 Paginationの⽐較 ● Offset Pagination ○ Pros ■ 実装は簡単 ■ あるアイテムの場所の特定がしやすい(何ページ目にいるのか) ○ Cons ■ リアルタイムで増減するデータにすぐ対応できない ● OffsetやLimitが固定であるので、タイミングによっては取得したい情報が参照で きない時がある ○ このようにならないために、limitが重要 ■ Offset考慮のため、件数が多くなるとパフォーマンスが低下する ● 位置依存性が比較的高いので

Slide 15

Slide 15 text

14 Paginationの⽐較 ● Offset Pagination ○ Pros ■ 実装は簡単 → 累積カウント数を次のoffsetとして利用してクエリすれば良い 40件検索した!! n回目の検索 n+1回目の検索 40件を飛ばして、 次の limit 件を とる!! カウントを引き継いで offsetとして利用

Slide 16

Slide 16 text

15 Paginationの⽐較 ● Offset Pagination ○ Pros ■ あるアイテムの場所の特定がしやすい(何ページ目にいるのか)     → Offsetは3で、次の検索でヒットしているから、2ページ目にいる!! 1 2 3 4 5 6 5

Slide 17

Slide 17 text

16 Paginationの⽐較 ● Offset Pagination ○ Cons ■ リアルタイムで増減するデータにすぐ対応できない Ex) Offset=3でLimit=3の検索の場合                   次に検索される予定のもの 1 2 3 4 5 6

Slide 18

Slide 18 text

17 Paginationの⽐較 ● Offset Pagination ○ Cons ■ リアルタイムで増減するデータにすぐ対応できない Ex) Offset=3でLimit=3の検索の場合 (検索中に2#という新しいデータを挿入) 1 2 3 4 5 6 2#

Slide 19

Slide 19 text

18 Paginationの⽐較 ● Offset Pagination ○ Cons ■ リアルタイムで増減するデータにすぐ対応できない Ex) Offset=3でLimit=3の検索の場合 1 2 3 4 5 6 2#

Slide 20

Slide 20 text

19 Paginationの⽐較 ● Offset Pagination ○ Cons ■ リアルタイムで増減するデータにすぐ対応できない Ex) Offset=3でLimit=3の検索の場合 1 2 3 4 5 6 2# 実際に検索されたもの

Slide 21

Slide 21 text

20 Paginationの⽐較 ● Offset Pagination ○ Cons ■ リアルタイムで増減するデータにすぐ対応できない → 重複カウントを引き起こす Ex) Offset=3でLimit=3の検索の場合 また数えられてて草
 1 2 3 4 5 6 2# 実際に検索されたもの

Slide 22

Slide 22 text

21 Paginationの⽐較 ● Offset Pagination ○ Cons ■ Offset考慮のため、件数が多くなるとパフォーマンスが低下する Ex) Don’t OFFSET Your SQL Query’s Performance (by Taras Drapalyuk in HACKERNOON) ● SELECT * FROM tasks ORDER BY id LIMIT 10 OFFSET 10; ○ Limit (cost=1.34..2.11 rows=10 width=628)… ● SELECT * FROM tasks ORDER BY id LIMIT 10 OFFSET 1000000; ○ Limit (cost=77270.24..77271.02 rows=10 width=628) https://hackernoon.com/dont-offset-your-sql-querys-performance

Slide 23

Slide 23 text

22 Paginationの⽐較 ● Offset Pagination ○ Cons ■ Offset考慮のため、件数が多くなるとパフォーマンスが低下する Ex) Don’t OFFSET Your SQL Query’s Performance (by Taras Drapalyuk in HACKERNOON) ● SELECT * FROM tasks ORDER BY id LIMIT 10 OFFSET 10; ○ Limit (cost=1.34..2.11 rows=10 width=628)… ● SELECT * FROM tasks ORDER BY id LIMIT 10 OFFSET 1000000; ○ Limit (cost=77270.24..77271.02 rows=10 width=628) https://hackernoon.com/dont-offset-your-sql-querys-performance 同じ10件でもコストが大きく異なる!!

Slide 24

Slide 24 text

23 Paginationの⽐較 ● Cursor Pagination ○ Pros ■ 件数が増えたときのパフォーマンスの低下が比較的緩い ● 無限スクロールなどに有利 ○ Ex ) X(旧Twitter)タイムライン ■ 新しいデータが入ってきても、柔軟に対応できる ○ Cons ■ Offsetを考慮しなくて良いがために、自分の位置の特定は難しい(ど のページのどこにいるのかなど) ● データは何かしらの順序性を持つことは必要 ○ カーソルはあくまでもその位置より前後しか情報を持たないので

Slide 25

Slide 25 text

24 Paginationの⽐較 ● Cursor Pagination ○ Pros ■ 件数が増えたときのパフォーマンスの低下が比較的緩い → オフセットなどを考慮せず、特定のカーソル(ex. ID)から取り出すことができ る!!(まあ、indexを張っていればのはなし...)

Slide 26

Slide 26 text

25 Paginationの⽐較 ● Cursor Pagination ○ Pros ■ 新しいデータが入ってきても、柔軟に対応できる → カーソルに指定するカラムは、基本的に順序性を担保している (ULIDなど) → 最新のデータなどは基本的に後方に配置され、重複表示などは防げ    る!!

Slide 27

Slide 27 text

26 Paginationの⽐較 ● Cursor Pagination ○ Cons ■ Offsetを考慮しなくて良いがために、自分の位置の特定は難しい(ど のページのどこにいるのかなど) → 1回の検索にて、次の検索時にはカーソルのみを保存する → あるコンテンツがどのページにいるのかは特定しにくい → ページ番号表示には不向き...(どこにいるのか分かりにくい...)

Slide 28

Slide 28 text

27 Paginationの使い分け ● Offset Pagination ○ Pros ■ 実装は簡単 ■ あるアイテムの場所の特定がしやすい(何ページ目にいるのか) ○ Cons ■ リアルタイムで増減するデータにすぐ対応できない ● OffsetやLimitが固定であるので、タイミングによっては取得したい情報が参照で きない時がある ○ このようにならないために、limitが重要 ■ Offset考慮のため、件数が多くなるとパフォーマンスが低下する ● 位置依存性が比較的高いので

Slide 29

Slide 29 text

28 Paginationの使い分け ● Offset Pagination ○ あるアイテムの場所の特定がしやすい(何ページ目にいるのか) → ページ番号付きのPaginationにぴったり!(前後が分かりやすい) 1 2 3 4 5 6

Slide 30

Slide 30 text

29 Paginationの使い分け ● Cursor Pagination ○ Pros ■ 件数が増えたときのパフォーマンスの低下が比較的緩い ● 無限スクロールなどに有利 ○ Ex ) X(旧Twitter)タイムライン ■ 新しいデータが入ってきても、柔軟に対応できる ○ Cons ■ Offsetを考慮しなくて良いがために、自分の位置の特定は難しい(ど のページのどこにいるのかなど) ● データは何かしらの順序性を持つことは必要 ○ カーソルはあくまでもその位置より前後しか情報を持たないので

Slide 31

Slide 31 text

30 Paginationの使い分け ● Cursor Pagination ○ 件数が増えたときのパフォーマンスの低下が比較的緩い ○ 新しいデータが入ってきても、柔軟に対応できる → 無限スクロールなどの検索件数の多いPaginationにぴったり! 1こめ 1こめ逃した... 面白かった!!

Slide 32

Slide 32 text

31 PaginationのSQLによる簡単な実装 ● Offset Pagination ○ SELECT * FROM users ORDER BY id DESC LIMIT 20 OFFSET 20; ○ OFFSET句を利用 ○ 逐次的なページングの際には ■ 検索後に累積カウント数を保存して、次の検索時にoffsetとして引き継ぐ ● Cursor Pagination ○ SELECT * FROM users WHERE id > 20 ORDER BY id DESC limit 20; ○ WHERE句を利用(Cursorは id=20 にあるという感じ) ○ Cursor対象になる列にはインデックスを張り、順序性を担保することが重要 ○ 逐次的なページングの際には ■ 検索後にCursorを保存して、次のページングの際に引き継ぐ

Slide 33

Slide 33 text

32 参考⽂献 ● Cursor Pagination ○ https://planetscale.com/learn/courses/mysql-for-developers/examples/cursor-pagination ● 図解ページネーション~オフセット・カーソル~ ○ https://note.com/note_fumi/n/nd5ee70a912d2 ● カーソルページネーションを実装した話 ○ https://lab.mo-t.com/blog/cursor-pagination-implementation ● GraphQL Cursor Connections Specification ○ https://relay.dev/graphql/connections.htm# ● Google Cloud - リストのページ分割 - ○ https://cloud.google.com/apis/design/design_patterns?hl=ja#list_pagination ● Don’t OFFSET Your SQL Query’s Performance ○ https://hackernoon.com/dont-offset-your-sql-querys-performance

Slide 34

Slide 34 text

33 イラスト利⽤ ● 指差しアイコン ○ https://illustcenter.com/2022/08/19/sdesign_00051/

Slide 35

Slide 35 text

34 Thank you