首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 高性能分页优化:仅首次查询总数,后续页复用总记录数减半数据库压力

     編輯:PHP 綜合知識

传统分页的性能瓶颈

常规分页每次请求执行两条 SQL:

  1. SELECT COUNT(*) FROM table 获取总记录数
  2. SELECT * FROM table LIMIT offset, size 获取当前页数据

高并发、大数据量下,COUNT(*) 扫描全表极其消耗资源,成为系统吞吐瓶颈。

优化思路:总数通过 URL 传递复用

首次请求查询总数,后续翻页通过 GET 参数传递 total,省去重复统计。

核心代码实现

<?php
// 配置
$pageSize = 10;
$page     = max(1, (int)($_GET['page'] ?? 1));

// 1. 获取总记录数:首次查询,后续复用
if (isset($_GET['total'])) {
    $total = (int)$_GET['total'];
} else {
    // 首次加载:执行 COUNT(*)
    $sql = "SELECT COUNT(*) AS total FROM `tablename`";
    $res = mysql_query($sql) or die(mysql_error());
    $row = mysql_fetch_assoc($res);
    $total = (int)$row['total'];
}

// 2. 无数据直接返回
if ($total === 0) {
    echo '暂无数据';
    exit;
}

// 3. 查询当前页数据
$offset = ($page - 1) * $pageSize;
$sql = "SELECT * FROM `tablename` LIMIT $offset, $pageSize";
$res = mysql_query($sql) or die(mysql_error());

// 4. 输出数据
while ($row = mysql_fetch_assoc($res)) {
    // 业务渲染...
    echo $row['title'] . '<br/>';
}

// 5. 生成分页链接(关键:带上 total 参数)
$baseUrl = "url.php?total=$total&page=";
$pageCount = ceil($total / $pageSize);

// 简单分页 HTML
echo '<div class="pagination">';
for ($i = 1; $i <= $pageCount; $i++) {
    $class = ($i === $page) ? ' class="active"' : '';
    echo "<a href=\"{$baseUrl}{$i}\"$class>[$i]</a> ";
}
echo '</div>';
?>

进阶优化方案对比

方案原理适用场景优点缺点
URL 传总数 (本文)首次查总数,后续透传中小数据量、翻页深度不大实现简单、零改造、兼容性好用户可篡改 total、深翻页仍需 COUNT
Redis 缓存总数写入/更新时同步计数器高并发、数据变化频繁毫秒级读取、彻底消除 COUNT需维护一致性、引入 Redis 依赖
延迟加载/无限滚动不显示总页数,仅加载下一页移动端、Feed 流、日志列表无需总数、体验流畅无法跳转指定页、SEO 不友好
近似总数EXPLAIN / 统计表 / 采样估算超大表 (亿级+)、允许误差极快、不锁表非精确、实现复杂
游标分页WHERE id > last_id LIMIT sizeID 单调递增、不需跳页避免 OFFSET 深翻页性能崩塌不支持随机跳页、需唯一有序键

最佳实践建议

  1. 首选 Redis 计数器:写入/删除时 INCR/DECR,读取 GET,彻底解决 COUNT 瓶颈。
  2. 深翻页必须用游标:OFFSET 1000000 会扫描 100 万行,改用 WHERE id > $lastId ORDER BY id LIMIT 20。
  3. URL 传总数作为过渡:无 Redis 环境时的低成本优化,注意校验 total 合法性(如 min(max($total, 0), $maxPossible))。
  4. 前端配合:PC 端保留页码跳转,移动端改用无限滚动或“加载更多”。

总结

“首次查总数,后续复用”是零依赖、低侵入的分页优化第一步。结合游标分页、Redis 计数器、前端交互调整,可构建支撑高并发大数据量的高性能分页体系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved