許多 PHP 分頁教學採用「每頁重新查詢資料庫 LIMIT offset, count」模式。當資料量達到百萬筆,OFFSET 深分頁會導致全表掃描,查詢時間隨頁碼線性增長。本文介紹一種「一次性全撈、記憶體切片」的替代方案,適合中小型資料集(如 < 5 萬筆)或內部管理系統,能消除深分頁效能問題並簡化程式邏輯。
$ListNum = 25。$Start_Num 參數決定起始位置(預設 0)。SELECT 所有符合條件記錄,逐筆迴圈計數 $n,僅將落在 [$Start_Num, $Start_Num + $ListNum) 區間的記錄存入輸出陣列 $artList。$n 即為總筆數,據此計算首頁、尾頁、上一頁、下一頁連結參數。<?php
$ListNum = 25;
$Start_Num = isset($_GET['start']) ? (int)$_GET['start'] : 0;
$conn = odbc_connect("DSN", "user", "password");
$sql = "SELECT field FROM table";
$result = odbc_exec($conn, $sql);
$artList = '';
$n = 0;
while (odbc_fetch_row($result)) {
if ($n >= $Start_Num && $n < $Start_Num + $ListNum) {
$val = odbc_result($result, "field");
$artList .= $n . $val . "<br>";
}
$n++;
}
// 計算尾頁起始位置
$lastPage = ($n % $ListNum == 0) ? $n - $ListNum : $n - ($n % $ListNum);
// 產生導航連結
$nav = "<br>|<最前一頁 ";
$nav .= ($Start_Num > 0) ? "<<上一頁 " : "<<上一頁 ";
$nav .= ($Start_Num < $n - $ListNum) ? "下一頁>> " : "下一頁>> ";
$nav .= "最後一頁>|<br>";
echo $artList . $nav;
?>
| 優點 | 缺點 |
|---|---|
| 無 OFFSET 深分頁效能衰退 | 資料集過大時記憶體壓力大 |
| 程式碼簡潔,單一查詢邏輯清晰 | 不適合高併發、海量資料公開網站 |
| 總筆數、總頁數自然獲得,無額外 COUNT 查詢 | 資料異動頻繁時易出現髒讀 |
odbc_pconnect 持久連線減少連線開銷。LIMIT + 索引優化的標準分頁,或引入 Redis 快取熱門頁面。Pager 類別,支援多種 URL 模式與樣式主題。理解不同分頁策略的權衡,才能根據業務規模選擇最適合的架構。本方案為中小型專案提供了「零複雜度、零深分頁痛點」的實用選項。