[英]Pagination Offset Issues - MySQL
我有一個包含 100 萬條記錄的訂單網格。 該頁面具有分頁、排序和搜索選項。 因此,如果排序順序是由帶有搜索鍵的客戶名稱設置的,並且頁碼為 1,則它工作正常。
SELECT * FROM orders WHERE customer_name like '%Henry%' ORDER BY
customer_name desc limit 10 offset 0
當用戶單擊最后一頁時,它會成為一個問題。
SELECT * FROM orders WHERE customer_name like '%Henry%' ORDER BY
customer_name desc limit 10 offset 100000
上面的查詢需要永遠加載。 索引設置為訂單id、客戶名稱、訂單日期列。
如果我沒有非主鍵排序選項,我可以使用此解決方案https://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/ ,但是在我的情況下,排序是用戶選擇的。 它將從訂單 ID、客戶名稱、訂單日期等更改。
任何幫助,將不勝感激。 謝謝。
問題1:
LIKE "%..."
-- 前導通配符需要對數據進行全面掃描,或者至少直到它找到 100000+10 行。 甚至
... WHERE ... LIKE '%qzx%' ... LIMIT 10
是有問題的,因為可能沒有 10 個這樣的名字。 所以,全面掃描你的百萬個名字。
... WHERE name LIKE 'James%' ...
將至少從表的中間開始——如果有一個以name
開頭的索引。 但是, LIMIT
和OFFSET
可能會合謀要求讀取表格的 rest。
問題 2:(在您編輯問題之前!)
如果你省略WHERE
,你真的希望用戶翻閱一百萬個名字來尋找東西嗎?
這是一個用戶界面問題。
如果您有一百萬行,並且 output 是按 Customer_name 排序的,那么很容易看到 Aarons 和 Zywickis,但看不到其他任何人。 你會怎么找到我(詹姆斯)? 要么你有 100K 鏈接,而我在中間的某個地方,要么可憐的用戶將不得不按 [Next] 'forever'。
我的觀點是,數據庫不是引入效率的地方。
在其他一些情況下,go 到[Next](或[Prev])頁面是有意義的。 在這些情況下,“記住你離開的地方”,然后用它來有效地進入桌子。 OFFSET
效率不高。 更多關於分頁
我為此使用了一個特殊的概念。 首先,我有一個名為pager
的表。 它包含一個主要的pager_id,以及一些用於標識用戶的值(user_id,session_id),這樣pager 數據就不會被竊取。
然后我有第二個名為pager_filter
的表。 我由 3 個 id 組成:
pager_id int unsigned not NULL # id of table pager
order_id int unsigned not NULL # store the order here
reference_id int unsigned not NULL # reference into the data table
primary key(pager_id,order_id);
作為第一個操作,我 select 匹配過濾器規則的所有記錄,並將它們插入到pager_filter
DELETE FROM pager_filter WHERE pager_id = $PAGER_ID;
INSERT INTO pager_filter (pager_id,order_id,reference_id)
SELECT $PAGER_ID pager_id, ROW_NUMBER() order_id, data_id reference_id
FROM data_table
WHERE $CONDITIONS
ORDER BY $ORDERING
填充過濾表后,您可以使用內部聯接進行分頁:
SELECT d.*
FROM pager_filter f
INNER JOIN data_table d ON d.data_id = f.reference id
WHERE f.pager_id = $PAGER_ID && f.order_id between 100000 and 100099
ORDER BY f.order_id
或者
SELECT d.*
FROM pager_filter f
INNER JOIN data_table d ON d.data_id = f.reference id
WHERE f.pager_id = $PAGER_ID
ORDER BY f.order_id
LIMIT 100 OFFSET 100000
提示:以上所有代碼都不是經過測試的偽代碼
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.