原文地址:We need tool support for keyset paginationsql
一、offset的定義數據庫
…the rows are first sorted according to the <order by clause> and then limited by dropping the number of rows specified in the <result offset clause> from the beginning…ide
SQL:2016, Part 2, §4.15.3 Derived tablespost
能夠簡單理解爲:查詢數據排序完後,使用遊標讀取數據,offset以前的數據所有「丟棄」掉,取出limit條數據便可。性能
二、offset分頁的問題.net
2.1 性能影響(深度分頁)postgresql
例如:每頁100條數據,要獲取第101頁的數據,等價於select xxx from table offset 10000 limit 100。實際上數據庫仍是須要取出10100條數據,只不過是「丟棄」了前10000條,而後獲取後面100條。blog
2.2 業務功能上的困擾排序
下圖能夠清晰的反映這個問題,如圖:ci
因爲第二步新紀錄的插入,致使同一條數據出如今第一頁(最後一條數據)和第二頁(第一條數據)。
三、拋棄offset(Life Without Offset)
如何不使用offset進行分頁? 咱們能夠經過查詢條件告訴數據庫「上次看到哪裏了」,而後接着看。
例如:
SELECT ...
FROM ...
WHERE ...
AND id < ?last_seen_id
ORDER BY id DESC
FETCH FIRST 10 ROWS ONLY
這裏一樣支持「多個字段排序的狀況」。
注意:這種方案的限制是——不能跳到指定的「頁」,只能一頁一頁的翻。
參考:Pagination done the Right Way