avatar
Articles
267
Tags
55
Categories
39

Home
Archives
Tags
Categories
List
  • Music
  • Movie
Link
About
平屋慢生活
Home
Archives
Tags
Categories
List
  • Music
  • Movie
Link
About

Pagination

Created2024-12-14|Updated2026-02-11|情報の存在論
|Post Views:

世界是一整本書,人生可以被清楚地切成第 1 頁、第 2 頁、第 50 頁,我只要照著頁碼翻,就一定能看到我該看到的那一段,像是 30 歲要做到第 30 頁、35 歲要結婚、40 歲要買房,同齡人u3已經在地第 20 頁,我怎麼還在第 15 頁?

因為你的人生座標來自「別人在哪一頁」,這就是 OFFSET FETCH!

a

感覺 OFFSET 規規矩矩的,一頁頁走應該沒甚麼問題,然而,OFFSET 有一個隱藏陷阱!

世界不是靜止的書,有人中途離場(刪資料)、有人突然插隊(新增資料),頁碼可能看起來沒有錯,但那一頁的內容已經變了,明明我照順序走,卻發現自己重複經歷同樣的痛苦,又或者莫名其妙的錯過了一些重要的東西,OFFSET 的人生,會迷失在比較與對齊之中。也不是說 OFFSET 是不好,但我們不能一直用 OFFSET 活著!

jk

Keyset 的世界觀就完全不同,我不管現在是第幾頁,我只記得我上一次走到哪裡,我知道自己現在的能力邊界,我清楚目前累積到哪個階段,下一步,只要比「現在的我」再前進一點,你不再問:「我是不是落後了?」而是問:「我是不是比昨天更靠前?」

不容易被插隊影響、不怕世界變動、不會因為別人刪掉或新增什麼,就懷疑自己整段旅程,因為人生不是靠「頁碼定位」,而是靠「狀態連續」

vv

「在已排序的結果集中,用明確的規則只取你想看的那一段資料」,讓資料查詢可以被「分頁」使用

1
2
3
4
5
SELECT emp_id, emp_name, salary
FROM employee
ORDER BY emp_id
OFFSET 20 ROWS -- 跳過前 20 筆
FETCH NEXT 10 ROWS ONLY; -- 取 10 筆資料

‵

  • FROM employee,從 employee 這張表把所有資料先拿出來(注意:此時還沒有分頁)
  • SELECT emp_id, emp_name, salary,指定你只關心這三個欄位,其他欄位先不理。
  • ORDER BY emp_id,先把「整個結果集」依 emp_id 排好順序,因為 OFFSET / FETC 一定是「對排序後的結果」動手
  • OFFSET 20 ROWS,把排序後的結果「前 20 筆直接丟掉不看」
  • FETCH NEXT 10 ROWS ONLY,在跳過前 20 筆之後,再拿接下來的 10 筆資料出來

「我要第 21~30 筆員工資料」

複雜但穩定 → SP 很香(效能也好控)

分頁邏輯放在哪裡,取決於「變動成本」要由誰承擔。當分頁查詢「長得都一樣」時交給 Stored Procedure,當使用端地應用也不用太擔心,因為我們不太會變動他

「後台訂單列表」永遠都有狀態、是否刪除、時間區間、固定幾種排序,而且可能 join 訂單、會員、付款、物流很多表,但需求很少變,這種放 SP,DB 可以針對固定查詢做索引/統計/最佳化,多系統共用同一支 SP,不會寫出不同版本

例如使用者清單、商品清單、訂單清單,選項只有那幾樣,固定排序(建立時間 / ID)、固定條件(狀態、是否刪除)、固定分頁(page + pageSize),若直接寫在 sp 優點是

  • DB 已最佳化
  • 查詢一致、好控管
  • 多個系統可共用

查詢方式一直變

「前台商品搜尋」join商品、分類、品牌、活動價、庫存、評價,但更麻煩的是一直加規則,本週主打要排前面、不同會員等級價格不同、A/B test 改排序策略、不同入口要插推薦/廣告,這種如果硬放 SP 會得到一支「超長 SP」,裡面塞一堆 if/動態 SQL,改一次很容易影響別的策略,測試成本飆升

ff

OFFSET 請資料庫「先走過不需要的資料,再把你要的那一小段拿出來」,而 Keyset 是讓「查詢條件本身就具有進度狀態」,而不是讓資料庫在結果集裡幫你計數,他用可比較的鍵值,將無狀態查詢轉為具狀態的資料存取

1
2
3
4
5
SELECT emp_id, emp_name, salary
FROM employee
ORDER BY emp_id
OFFSET 20 ROWS -- 跳過前 20 筆
FETCH NEXT 10 ROWS ONLY; -- 取 10 筆資料

隨著 OFFSET 的增加,速度會越來越慢;因為即使我們只需要返回 10 條記錄,資料庫仍然需要訪問並且過濾掉 N(比如 1000000)行記錄,即使 id 有建立索引,OFFSET 的效能問題仍然存在。索引雖然能讓排序更快,但仍要遍歷前 N 筆索引項目。也就是說,它只是「有順序地走很快」,但…還是要走過去

a

cc

c

與其讓資料庫「跳過」一堆資料,不如我們自己記住「上一頁最後一筆的 id」,這種方式被稱為 Keyset Pagination 或 Seek Method

1
2
3
4
SELECT TOP 10 *
FROM employee
WHERE emp_id > @last_id
ORDER BY emp_id;

如果 id 欄位上存在索引,這種分頁查詢的方式可以基本不受資料量的影響!

aa

gh

有的需求,用 Keyset Pagination 就會變得相當麻煩

  • 「跳到第 50 頁」
  • 「依 salary DESC 分頁」
  • 「排序條件由使用者自由切換」

這些操作更適合用 OFFSET,或其他折衷方式處理

  • 後台管理系統 → OFFSET(資料量可控)
  • API / 無限滾動 → Keyset
  • 排行榜 → 預先計算 / 快取

適合使用 OFFSET 的情境像是

  • ✔ 資料量小(幾千筆以內)
  • ✔ 後台管理頁(偶爾用)
  • ✔ 需要「跳頁」功能(例如直接到第 50 頁)

cc

問問自己,你到底是想「瀏覽資料」,還是「定位資料」?

  • 瀏覽 → Cursor / Keyset
  • 定位 → 搜尋條件 + Index

像 Instagram、Twitter 從來不會有「跳到第 1000 頁」這種操作,因為它們的核心體驗是一直滑一直爽

  • 社群動態(Facebook / IG / Twitter)
  • 電商商品列表
  • 訂單紀錄
  • 日誌(Log)
  • 無限滾動(Infinite Scroll)
  • API 分頁(效能關鍵)

「線上系統、高流量系統」需要考慮使用 Keyset Pagination

Cc

這時候兩者的本質差異就顯現出來了

  • OFFSET 分頁是「位置導向」
  • Keyset 分頁是「值導向」

當資料變動時 OFFSET:頁面會「漂移」、Keyset:結果仍然連續,OFFSET 的隱性風險不是慢,而是「不一致」

使用者打開第 1 頁,中間有人刪掉一筆資料,接著使用者點第 2 頁 → 結果出現「資料重複」或「資料被跳過」,這種情況在高一致性場景(像交易紀錄)是不可以接受的

c

c

Author: Chi-KEKE
Link: https://chi-keke.github.io/2024/12/14/DeepType-SQL-Pagination/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
情報の存在論
cover of previous post
Previous
取得系統資訊
cover of next post
Next
86 不存在的戰區 - 請為自己努力活過而感到驕傲
Related Articles
cover
2024-06-08
Anti Join
cover
2025-10-09
Datetime Flow
cover
2025-10-12
Index - 發揮作用...了嗎
cover
2025-10-04
Index
cover
2025-12-06
ReadUncommitted and SnapShot
cover
2025-12-10
Pre-filtering vs. Post-filtering
avatar
Chi-KEKE
Articles
267
Tags
55
Categories
39
Follow Me
Announcement
世界上總會有一些溫暖的小角落
Contents
  1. 1. 複雜但穩定 → SP 很香(效能也好控)
  2. 2. 查詢方式一直變
  3. 3. 問問自己,你到底是想「瀏覽資料」,還是「定位資料」?
Recent Post
Hallucination
Hallucination2027-03-16
Untitled
Untitled2026-08-30
Untitled
Untitled2026-08-30
Untitled
Untitled2026-08-30
Untitled
Untitled2026-08-30
©2024 - 2026 By Chi-KEKE
Framework Hexo|Theme Butterfly
What you'll find out there is boundless freedom !