水平分庫分表後的分頁查詢

2021-09-27 12:20:13 字數 2328 閱讀 3708

分庫後,分頁查詢按照時間time來排序order by。

若查詢第x頁的資料,每頁y條。一共n個庫。

步驟:將order by time offset (x*y+1) limit y,改寫成order by time offset 0 limit (x*y+1) +y

服務層將改寫後的sql語句發往各個分庫:即每庫各取x頁的資料

服務層將得到 n*(x*y+1+y) 條資料

服務層對得到的資料進行記憶體排序,記憶體排序後再取偏移量x*y+1後的y條記錄,就是全域性視野所需的一頁資料

查詢第1頁資料

每個庫執行order by time where time>0 limit y

得到 n*y條資料,記憶體排序,得到前y條,即為第1頁。

$time_max=第1頁最大的time

獲取第2頁資料

每個庫依次查詢

order by time where time>$time_max limit y

一共得到n*y條資料,取time最小的y條為第2頁資料。

$time_max=第2頁最大的time

資料的傳輸量和排序的資料量不會隨著不斷翻頁而導致效能下降。

為了方便舉例,假設2個庫,一頁5條資料,查詢第200頁的sql語句為select * from t order by time offset 1000 limit 5;

查詢改寫

改寫為select * from t order by time offset 500 limit 5,並投遞給所有的分庫,注意,這個offset的500,來自於全域性offset的總偏移量1000,除以水平切分資料庫個數2。

如果是3個分庫,則可以改寫為select * from t order by time offset 333 limit 5

假設這三個分庫返回的資料(time, uid)如下:

每個分庫都返回的按照time排序的一頁資料。

找到所返回3頁全部資料的最小值

第乙個庫,5條資料的time最小值是1487501123

第二個庫,5條資料的time最小值是1487501133

第三個庫,5條資料的time最小值是1487501143

故,三頁資料中,time最小值來自第乙個庫,time_min=1487501123,這個過程只需要比較各個分庫第一條資料。

查詢二次改寫

第二次要改寫成乙個between語句,between的起點是time_min,between的終點是原來每個分庫各自返回資料的最大值:

第乙個分庫,第一次返回資料的最大值是1487501523

所以查詢改寫為select * from t order by time where time between time_min and 1487501523

第二個分庫,第一次返回資料的最大值是1487501323

所以查詢改寫為select\ * from t order by time where time between time_min and 1487501323

第三個分庫,第一次返回資料的最大值是1487501553

所以查詢改寫為select * from t order by time where time between time_min and 1487501553

第二次查詢會返回比第一次查詢結果集更多的資料,假設這三個分庫返回的資料(time, uid)如下:

在每個結果集中虛擬乙個time_min記錄,找到time_min在全域性的offset

故:time_min在第乙個庫的offset是333;

time_min在第二個庫的offset是331;

time_min在第三個庫的offset是330;

綜上,time_min在全域性的offset是333+331+330=994;

得到time_min在全域性的offset,就相當於有了全域性視野,根據第二次的結果集,就能夠得到全域性offset 1000 limit 5的記錄

第二次查詢在各個分庫返回的結果集是有序的,又知道了time_min在全域性的offset是994,一路排下來,容易知道全域性offset 1000 limit 5的一頁記錄(上圖中黃色記錄)。

Sharding JDBC 實現水平分庫分表

1 需求分析 cid bigint 20 not null,cname varchar 50 null,user id bigint 20 null,cstatus varchar 10 null,primary key cid create table edu db 1 course 2 cid ...

什麼是垂直分庫分表,水平分庫分表

垂直分片 按照業務拆分的方式稱為垂直分片,又稱為縱向拆分,它的核心理念是專庫專用。在拆分之前,乙個資料庫由多個資料表構成,每個表對應著不同的業務。而拆分之後,則是按照業務將表進行歸類,分布到不同的資料庫中,從而將壓力分散至不同的資料庫。下圖展示了根據業務需要,將使用者表和訂單表垂直分片到不同的資料庫...

你分庫分表的姿勢對麼? 詳談水平分庫分表

一 背景 提起分庫分表,對於大部分伺服器開發來說,其實並不是乙個新鮮的名詞。隨著業務的發展,我們表中的資料量會變的越來越大,欄位也可能隨著業務複雜度的公升高而逐漸增多,我們為了解決單錶的查詢效能問題,一般會進行分表操作。同時我們業務的使用者活躍度也會越來越高,併發量級不斷加大,那麼可能會達到單個資料...