- 作為后端攻城獅,在接到分頁list需求的時候,內心是這樣的
- 畫面是這樣的
- 代碼大概是這樣的
- select count(id) from … 查出總數
- select * from …. limit m,n 查出分頁數據
- 和前端的交互是這樣的
- 你傳給我查詢條件和pageNum、pageSize
- 我給你返回total、resultList
- 恩,可以開始預估開發時間了
- 結果出來的時候是這樣的
- 在點擊后面幾頁的時候發現數據加載很慢。不好,一開始沒想到數據量是這個級別的,慢SQL監控已經開始預警
- 定位到原因有兩個
- select count(*) 總量會掃全表
- limit m,n 當偏移量m很大的時候,查詢每次都要先掃到m條滿足條件的記錄
- 其他人一定也遇到過這個問題,打開百度還沒開始搜索就找到了一個解決方案,百度是這樣做的
- (正解)我去,這不是耍流氓嗎
- 沒有總數,就不需要count,第一個問題解決
- limit m,n 百度出來的解決方案都是加一個唯一標識去記錄上一次查詢的記錄在哪里
- 百度這種做法是搜索引擎自帶的分頁,不過mysql分頁同樣可以借鑒,找來產品大大溝通一發
- “面對這么多的數據,只要把新的數據放到前面,用戶不會care后面的數據,是不是可以把頁碼干掉”
- “ 用戶也不會管我們到底有多少條記錄,來這里也只是做檢索而已,總數也可以去掉的,如果要統計數據量我們再單獨統計”
- 。。。理由還可以有很多,產品大大還是很好說話的
- 最后設計出來是這樣的
-
代碼實現是這樣的
-
id是自增主鍵
-
select * from … where id > y order by id limit n (向下翻頁)
- select * from … where id < y order by id desc limit n (向上翻頁)
-
- 和前端的交互是這樣的
- 你告訴我是向上翻頁還是向下翻頁,給我當前頁第一條(上一頁)或者最后一條(下一頁)記錄的id
- 我給你數據數據
- 總結
- 重點是在傳統分頁方案上遇到的兩個問題
- select count(*) 總量會掃全表
- limit m,n 當偏移量m很大的時候,查詢每次都要先掃到m條滿足條件的記錄
- 解決方案是產品和技術共同確認的結果,如果產品不接受,此方案不可行
-
實際開發中還會碰到的問題
- 上一頁/下一頁、沒有數據的處理方式
- 查詢自身帶有排序條件,需要order by多字段
- 重點是在傳統分頁方案上遇到的兩個問題