分佈式 - 跨庫分頁

select * from T order by time offset X limit Y 的跨M個庫分頁。

全局

每一個庫都必須返回 X+Y 個數據,所獲得的 M*(X+Y) 在服務層進行內存排序,而後再取總的偏移量X後的Y條記錄。算法

  • 優勢: 精準返回所需數據。
  • 缺點: (1)每一個分庫須要返回更多的數據,佔用網絡帶寬;(2)須要服務層的計算;(3)這個算法隨着頁碼的增大(即X的增大),性能平方級降低。

禁止跳頁查詢(業務折衷)

獲取第一頁的方式和全局策略是同樣的,但獲取第N頁(N>1)時,咱們取 N-1 頁的最大time,即time_max, 對於每一個分庫執行 select * from T order by time where time > time_max limit Y,這樣在服務層再總排序取前Y條記錄。sql

  • 優勢: 相比全局策略的性能平方級降低,該策略的性能是恆定的。
  • 缺點: 禁止跳頁查詢。

[推薦] 二次查詢

數學原理:對於一個有序序列分紅 M 個長度不等的有序子序列,M個有序子序列中每一個有序子序列前X個元素中的最大值集中起來,再取其中最小值,則該最小值必定小於等於原來有序序列的第 M*X 個元素值。
假設該最小值大於原序列的第 MX 個元素值,那麼M個有序子序列後面第X+個元素值都大於原序列的第 MX 個元素值,即構成原序列前MX 個元素只能是M個有序子序列的前X-個元素,由於MX- < M*X,因此假設不成立。網絡

步驟:性能

  1. 改寫分庫sql爲: select * from T order by time offset ceil(X/M) limit Y
  2. 獲取全部分庫sql中返回的最小time中的最小time,即time_min(詳見上面原理)
  3. 改寫分庫sql爲:select * from T order by time between time_min and 各自分庫的最大time(從第1步中獲得)
  4. 第3步的各個分庫的返回結果比第一步多,固然time_min的那個分庫的返回結果確定不變(因此time_min的那個分庫的sql在實現時能夠不用執行)。假設全部分庫總共多出 K 條數據,則全局_offset = ceil(X/M) * M - K 。(詳見上面原理)
  5. 將第3步返回的結果集合並,即第一條數據就是time_min的那條,其_offset由第四步已經獲得;咱們直接在該結果集的中從第(原始sql的offset - _offset + 2)條數據開始獲取Y條數據。
  • 優勢: 該策略的性能是幾乎恆定。
  • 缺點: 兩次查詢;內存中要將結果集合並。
相關文章
相關標籤/搜索