千萬數據,如何快速商品分頁

準備數據

MySQL的limit子句的語法,我們是非常熟悉的,查詢的起始位置不同,消耗的時間也是不一樣的。
我們創建一個數據表t_test:

字段名 類型 長度 小數點 不是 null 虛擬
id int 0 0
val varchar 255 0

我們接下來往數據表裏添加1000萬條數據,怎麼導入呢?先把數據寫到文件裏面,再導入到表裏,先來看下生成數據的java代碼吧

public class Demo2{
	public static void main(String [] args){
		try{
			FileWriter w=new FileWriter("E:/1.txt");
			BufferedWriter bw=new BufferedWriter(w);
			for(int i=1; i<=10000000;i++){
				String uuid=UUID.randomUUID().toString();
				bw.write(i+","+uuid+"\n");
			}
			bw.close();
			w.close();
			System.out.println("執行完畢");
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

接下來通過navicat在數據表t_test上右鍵->導入數據,
在這裏插入圖片描述
可以看到,默認選擇的就是txt類型的文件,直接點下一步選文件,直接下一步下一步的,大概需要10分到20分鐘的導入時間。
爲什麼使用文件導入,不適用insert執行呢?因爲insert是帶着事務的,1000萬條數據是很慢的,但是使用文檔導入是沒有帶事務的,速度是很快的。

優化前

我們接下來,看看limit子句的消耗時間

select id,name from t_test limit 100,100;
select id,name from t_test limit 10000,100;
select id,name from t_test limit 100000,100;
select id,name from t_test limit 1000000,100;

等待的時間是查詢越靠後返回的數據越慢,返回的時間可能不是幾秒,而是幾十秒幾百秒了。

優化辦法1:主鍵索引

select * from t_test where id>=5000000 limit 100;
select * from t_test where id>=5000000 and id<5000000+100;

主鍵索引耗時是0.01s,這個優化是幾百倍的提升

優化辦法2:用索引表加速

物理刪除會造成主鍵的不連續,這樣辦法1利用主鍵去進行分頁查詢的方法行不通了。如果邏輯刪除,等到數據從數據表中刪除轉到歷史表,那主鍵還是不連續。那還有什麼辦法來加速分頁查詢嗎?當然有,一個折中的辦法——從主鍵的索引進行加速,從索引表裏提取主鍵值,然後表做連接,從業務表裏再取數據。怎麼做呢?

首先我們要明白一個事情,我們給某個字段創建索引,那麼數據庫就會給某個字段創建一個索引表,這個索引表是二叉樹的,記錄的信息就是字段的值和主鍵的值,當我們使用索引字段作爲查詢條件,Mysql就會在二叉樹裏快速的定位到數據,然後取到主鍵的信息,再去關係表裏,根據主鍵值來查找數據,所以就是這麼來完成加速的

然後,我們看下如何對主鍵不連續的值,建立索引,看下面sql

select t.id,t.name from t_test t 
join (select id from t_test limit 5000000 ,100) tmp on t.id=tmp.id

看join後的子查詢,注意查詢的只是id主鍵的值,我們知道索引裏面是包含主鍵的值,這樣查詢就不用再走表了,直接查索引就行了,所以查詢的時候會用索引表加速

這樣速度比起沒有優化時候要強點,但是也不是很強,如果優化前是3.9s多,那優化後是2.7s,比起通過where id>=5000000 limit 100 這種方式提升的還是差的很多 ,不過也是提升了1.2s,這已經是主鍵不連續的情況最好的sql語句了。

其它解決辦法

結合業務上的一些設置,禁止查詢早期數據。
比如支付寶上面查詢不到幾年前的一筆大額轉賬,數據是不可能丟失的,只不過支付寶不讓你查詢很早以前的數據。
再比如在百度上搜索信息,只能搜索到76頁,更早的數據百度是不讓你去看的,如果不信,可以在百度上搜索任意一個熱門信息,最多隻能看到76頁。

總結

如何快速分頁查詢數據?

  1. 使用上面優化辦法2的sql語句,對主鍵不連續的數據進行查詢加速
  2. 在業務上,限制用戶查詢很靠後的數據
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章