面試xxx電商公司時 被問到分頁量特別大的時候怎麼處理--深度分頁

其實這不就是個深度分頁的概念嘛,然並軟 一臉懵 並不知道啥是深度分頁。

下面我們以一個實例,講解一下分頁性能問題。假設有一張 300w 條數據的表,對其進行分頁查詢。

select * from tbl_works limit 1, 10 // 32.8ms
select * from tbl_works limit 10, 10 // 34.2ms
select * from tbl_works limit 100, 10 // 35.4ms
select * from tbl_works limit 1000, 10 // 39.6ms
select * from tbl_works limit 10000, 10 // 5660ms
select * from tbl_works limit 100000, 10 // 61.4 秒
select * from tbl_works limit 1000000, 10 // 273 秒
可以看到,隨着偏移量(offset)的增加,查詢時間變得越長。對於普通的業務而言,超過1秒的查詢是絕對不可以忍受的。上例中,當偏移的起始位置超過10萬時,分頁查詢的時間超過61秒。當偏移量超過100萬時,查詢時間竟然長達273秒。

從上例中,我們可以總結出:LIMIT分頁查詢的時間與偏移量值成正比。當偏移量越大時,查詢時間越長。這種情況,會隨着業務的增加,數據的增多,會越發的明顯。那麼,如何優化這種情況呢?答案是,覆蓋索引。

1)子查詢分頁方式

SELECT * FROM tbl_works
WHERE id >= (SELECT id FROM tbl_works limit 100000, 1)
LIMIT 20  // 54ms

2)join 分頁方式

SELECT * FROM tbl_works t1 
JOIN (SELECT id from tbl_works WHERE status=1 
limit 100000, 10) t2
ON t1.id = t2.id  // 53.6 ms

這條SQL的含義是,通過自連接與join定位到目標 ids,然後再將數據取出。在定位目標 ids時,由於 SELECT的元素只有主鍵 ID,且status 存在索引,因此MySQL只需在索引中,就能定位到目標 ids,不用在數據文件上進行查找。因而,查詢效率非常高。

覆蓋索引(Cover Index)

如果索引包含所有滿足查詢需要的數據的索引成爲覆蓋索引(Covering Index),也就是平時所說的不需要回表操作。

簡單的說,覆蓋索引覆蓋所有需要查詢的字段(即,大於或等於所查詢的字段)。MySQL可以通過索引獲取查詢數據,因而不需要讀取數據行。

覆蓋索引的好處:

索引大小遠小於數據行大小。因而,如果只讀取索引,則能極大減少對數據訪問量。
索引按順序儲存。對於IO密集型的範圍查詢會比隨機從磁盤讀取每一行數據的IO要少。
避免對主鍵索引的二次查詢。二級索引的葉子節點包含了主鍵的值,如果二級索引包含所要查詢的值,則能避免二次查詢主鍵索引(聚簇索引,聚簇索引既存儲了索引,也儲存了值)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章