LIMIT 1000000, 20 會讓 MySQL 掃描 1,000,020 行再丟棄前 100 萬行,平均掃描半張表,隨資料增長線性惡化。優化核心思路:先用覆蓋索引快速定位主鍵,再回表取完整行。
-- 原始:全表掃描 2313 萬行
EXPLAIN SELECT * FROM user_order_info LIMIT 1000000,5;
-- type=ALL, rows=23131886, Extra=NULL
-- 優化:覆蓋索引子查詢 + JOIN 回表
EXPLAIN SELECT * FROM user_order_info
INNER JOIN (SELECT pin FROM user_order_info LIMIT 1000000,5) AS lim USING(pin);
-- 子查詢: type=index, key=PRIMARY, rows=23131886, Extra=Using index
-- 外層: type=eq_ref, key=PRIMARY, rows=1
SELECT pin FROM ... LIMIT ... 僅讀取主鍵索引 (Using index),不回表,I/O 極小。eq_ref 精準回表,僅讀 5 行完整資料。WHERE id > last_seen_id ORDER BY id LIMIT 20,無偏移量問題,效能恆定,適合無限滾動/APP 列表。EXISTS / IN 子查詢達成同樣效果。Handler_read_key / Handler_read_rnd_next 驗證優化效果。