推薦閱讀
1. SpringBoot 整合篇
2. 手寫一套迷你版HTTP伺服器
3. 記住:永遠不要在MySQL中使用UTF-8
4. Springboot啟動原理解析
最近遇到了這麼一個情況,資料庫裡面的數據由於長期的堆積,導致數據量不斷的上升,而後臺的系統每次進行分頁查詢的時候,效率都會降低很多。後來查看了一下之後,發現此時的分頁原理主要是採用了傳統的物理分頁 limit n,m 的方式。
為了方便演示,我特意創建了以下幾張表進行實例演練:
表分別是商品表,用戶表,用戶選購商品記錄表:
goods user g_u
三張表的關係比較簡單,user的id和goods裡面的id合併生成關聯數據,存儲在了g_u裡面。三張資料庫表的設計如下所示:
CREATE TABLE `goods` (
`id` int(11) NOT NULL,
`name` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
`price` decimal(6,1) NOT NULL,
`des` varchar(40) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`age` tinyint(3) NOT NULL,
`sex` tinyint(1) NOT NULL COMMENT 年齡,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
CREATE TABLE `g_u` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`g_id` int(11) NOT NULL COMMENT 商品id,
`u_id` int(11) NOT NULL COMMENT 用戶id,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2800001 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
這個模擬的應用場景非常簡單,用戶和商品之間的關係維持在了一對多的關聯中。為了方便進行後續的測試,我用jmeter批量創建了1900000條測試數據,模擬一次百萬級的數據查詢場景。
相應的數據腳本也已經存在百度雲中了,需要的同學可以前往下載:
地址:
鏈接: https://pan.baidu.com/s/1BfddJ8MBtnpeiV84gNmClA
提取碼: 4kmp
假設現在需求裡面有這樣的一個業務場景,需要我們對購買記錄表裡面的數據進行分頁查詢,那麼對於常規的分頁查詢操作,常人會想到的方式可能是通過下述的語句:
SELECT * from g_u as gu ORDER BY id limit 1850000,100
測試一下發現,查詢的時間為: