
本文介绍如何在 php 中通过 mysqli 获取查询结果集的总行数,避免重复执行耗时查询,适用于分页、限流或资源受限环境下的高效数据处理。
本文介绍如何在 php 中通过 mysqli 获取查询结果集的总行数,避免重复执行耗时查询,适用于分页、限流或资源受限环境下的高效数据处理。
在 Web 开发中,尤其是面对大数据量的视频/音乐内容表(如 videoname),常需统计每首歌曲被点击的次数,并支持分页展示(例如每次加载 50 条)。你提出的原始 SQL:
SELECT mv.id, mv.songname, mv.slug,
(SELECT COUNT(*) FROM clickedsongname WHERE clickedsongname.songid = mv.id) AS click_count
FROM videoname mv;
虽能正确返回每条歌曲及其点击量,但若直接用 COUNT(*) 包裹整个查询(如 SELECT COUNT(*) FROM (...) AS t),不仅语法错误(因混用了聚合与非聚合字段),更会导致性能浪费——你本意是先获知总行数以规划分页逻辑,再按需取子集,而非对全表做两次完整扫描。
✅ 正确解法:不在 SQL 中硬编码计数,而由 PHP 层在执行一次查询后即时获取结果集行数。这既符合“只查一次”的优化原则,又规避了 SQL_CALC_FOUND_ROWS(已弃用)或额外 COUNT(*) 子查询的开销。
使用 MySQLi 扩展,只需三步:
- 建立连接并执行查询;
- 调用
mysqli_num_rows()获取结果集中实际返回的行数; - 根据该数值动态构造分页参数(如
LIMIT 50 OFFSET 0→LIMIT 50 OFFSET 50)。
示例代码(含错误处理与资源释放):
<?php $host = 'localhost';
$user = 'your_user';
$pass = 'your_pass';
$db = 'your_db';
// 创建连接
$con = mysqli_connect($host, $user, $pass, $db);
if (!$con) {
die('Connection failed: ' . mysqli_connect_error());
}
// 执行主查询(含子查询统计)
$query = "SELECT mv.id, mv.songname, mv.slug,
(SELECT COUNT(*) FROM clickedsongname WHERE songid = mv.id) AS click_count
FROM videoname mv";
$result = mysqli_query($con, $query);
if (!$result) {
die('Query failed: ' . mysqli_error($con));
}
// ✅ 关键:获取结果集总行数(不触发新查询!)
$totalRows = mysqli_num_rows($result);
echo "共检索到 {$totalRows} 首歌曲。\n";
// 示例:分页逻辑(每页50条)
$limit = 50;
$pages = ceil($totalRows / $limit);
echo "共 {$pages} 页(每页{$limit}条)\n";
// 清理资源
mysqli_free_result($result);
mysqli_close($con);
?>
⚠️ 注意事项:
-
mysqli_num_rows()仅对SELECT、SHOW、DESCRIBE、EXPLAIN等返回结果集的查询有效;对INSERT/UPDATE/DELETE应使用mysqli_affected_rows()。 - 若使用
mysqli_query()的缓冲模式(默认),mysqli_num_rows()可立即返回;若启用MYSQLI_USE_RESULT(流式读取),则必须先遍历完结果集才能调用,否则返回0。 - 对超大表(如千万级
videoname),即使只查行数也建议为clickedsongname.songid添加索引,加速子查询:
ALTER TABLE clickedsongname ADD INDEX idx_songid (songid);
总结:与其在 SQL 层反复尝试“伪计数”,不如信任 PHP 的 mysqli_num_rows() —— 它轻量、准确、零额外开销,是分页场景下获取总记录数最推荐的实践方式。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











