Mysql
MySQL - 基於 UUID/created_at 游標的分頁?
對於大型數據集,使用 an 進行分頁
OFFSET
是很慢的,並不是最好的分頁方式。更好的分頁方法是使用游標,它只是行上的唯一標識符,因此我們知道從上一個游標位置上次離開的位置繼續分頁的位置。當涉及到一個自動遞增
id
值的游標時,它很容易實現:SELECT * FROM users WHERE id <= %cursor // cursor is the auto incrementing id, ex. 100000 ORDER BY id DESC LIMIT %limit
我們不確定的是,如果不是自動遞增
id
游標,游標的唯一唯一順序標識符是表行上的uuid
和。created_at
我們當然可以根據 查詢
uuid
得到created_at
,然後選擇所有users
的,<= created_at
但問題是如果表中有多個相同created_at
時間戳的實例users
怎麼辦?知道如何users
根據uuid/created_at
游標組合查詢表以確保我們獲得正確的數據集(就像我們使用自動遞增一樣id
)?同樣,唯一唯一的欄位是uuid
因為created_at
可能是重複的,但它們的組合每行都是唯一的。
我會回答你的問題,但首先讓我告訴你,我不明白你為什麼要這樣做。自動增量 ID 非常適合此任務。但是使用時間戳列也是正確的,因為依賴 id 進行排序是一種不好的做法。為什麼?因為在某些情況下,它的順序可能不是按時間順序排列的——例如,如果您使用 Galera 集群並且您有故障轉移。
要按照您的要求進行操作,請首先創建此索引:
ALTER TABLE users ADD INDEX idx_created_at_uuid (created_at, uuid);
順序列很重要。如果你反轉它,索引將沒有用。
現在您只需要執行這樣的查詢:
SELECT some_columns FROM users WHERE created_at <= x AND uuid = y ORDER BY created_at DESC;
uuid
只需要因為 created_at 不是唯一的。如果created_at
不是第一列,MySQL 將不得不讀取所有行並將它們複製到臨時表(可以是記憶體中或磁碟上)以對它們進行排序。如果您決定使用 id,只需保留上述程式碼段,但替換
uuid
為id
.