表 collect(id, title, info, vtype),10 萬條數據測試:
LIMIT 1000,10 → 0.01sLIMIT 90000,10 → 8-9s(隨偏移量線性增長)
SELECT id, title FROM collect
WHERE id >= (SELECT id FROM collect ORDER BY id LIMIT 90000, 1)
LIMIT 10;
利用主鍵索引定位起始 ID,再回表取列,速度提升至 0.04s。
SELECT id FROM collect WHERE vtype=1 ORDER BY id LIMIT 90000,10; -- 8-9s
雖 vtype 有索引,但 LIMIT 大偏移仍需掃描大量索引葉子節點。
-- 關鍵:WHERE 列在前,ORDER BY 列在後,僅 SELECT 索引列
ALTER TABLE collect ADD INDEX idx_vtype_id (vtype, id);
SELECT id FROM collect WHERE vtype=1 ORDER BY id LIMIT 90000,10; -- 0.04s ✅
核心原則:WHERE 列優先,ORDER BY / LIMIT 列次之,SELECT 僅取索引列(覆蓋索引),避免回表。
-- 1. 只走覆蓋索引取 ID 字符串
SELECT id FROM collect WHERE vtype=1 ORDER BY id LIMIT 90000,10;
-- 拼成 '90001,90002,...'
-- 2. 主鍵 IN 查詢回表取完整數據
SELECT id, title, url, ... FROM collect WHERE id IN (90001,90002,...); -- 0.00s ✅
PHP 代碼片段:
$db->pagesize = 20;
$sql = "SELECT id FROM collect WHERE vtype=$vtype";
$db->execute($sql);
$strpage = $db->strpage(); // 保存分頁 HTML
$ids = [];
while ($rs = $db->fetch_array()) $ids[] = $rs['id'];
$id_str = implode(',', $ids);
$db->pagesize = 0; // 關閉分頁
$db->execute("SELECT id,title,url,... FROM collect WHERE id IN ($id_str)");
// 輸出數據 + $strpage
| 方案 | LIMIT 90000,10 | LIMIT 900000,10 |
|---|---|---|
| 原始 Limit | 8-9s | 不可用 |
| 覆蓋索引 | 0.04s | 0.49s |
| 覆蓋索引 + IN 回表 | 0.04s + 0.00s | 0.49s + 0.00s |
作者:ERDP技術架構