SELECT COUNT() 与 mysql_num_rows();

Posted

技术标签:

【中文标题】SELECT COUNT() 与 mysql_num_rows();【英文标题】:SELECT COUNT() vs mysql_num_rows(); 【发布时间】:2012-10-03 14:14:09 【问题描述】:

我有一个大表 (60+) 数百万条记录。

我正在使用 php 脚本浏览此表。

PHP 脚本(带有分页)加载速度非常快,因为:

表引擎是 InnoDB,因此 SELECT COUNT() 非常慢,mysql_num_rows() 不是一个选项,所以我将总行数(我用来生成分页的数字)保存在一个单独的表中(我更新了这条记录total_rows=total_rows-1total_rows=total_rows1+1DELETEINSERT 期间)。

但问题是如何处理搜索结果的分页?

现在我分两步进行:

1.

$condition = " fname='rinchik' ";
$result = "SELECT * FROM my_large_table WHERE" . $condition;

这里我从数据库中得到了所有的搜索结果。

2。 现在我需要计算这些结果来创建分页。 我正在这样做:

$condition; <- we already have this from the step 1
$result_count = "SELECT COUNT(id) FROM my_large_table WHERE" . $condition;

而且有点慢。

如果我这样做(只需一步)会更好吗?:

$condition = " fname='rinchik' ";
$result = "SELECT * FROM my_large_table WHERE" . $condition;
$result_count = mysql_num_rows($result);

【问题讨论】:

根据经验,您对数据库的调用越少,您的代码就会越快。 而不是COUNT(id)(这需要MySQL检查每条记录的id是否为NULL,因此应该从计数中排除),您应该使用COUNT(*)。跨度> @eggyal ID 永远不会为空。我不确定检查过程,但我认为只有在为列设置“ALLOW NULL”时才会出现这种情况。 @rinchik:这是COUNT(expr, ...)COUNT(*) 的语义。 @AntonSoradoi 这是我知道的一般规则。总有一些例外。 【参考方案1】:

使用 COUNT(id)。它只返回计数,使用mysql_num_rows($result); php 从mysql 中获取所有数据并计算找到的结果数。

最后,不要使用 mysql_* 函数。

建议的替代品

不鼓励使用此扩展程序。相反,MySQLi 或 PDO_MySQL 应该使用扩展名。另请参阅 MySQL:选择 API 指南和 有关更多信息的常见问题解答。此功能的替代品 包括:

mysqli_stmt_num_rows() PDOStatement::rowCount()

【讨论】:

然后将其应用于 mysqli_num_rows【参考方案2】:

使用COUNT,服务器内部会以不同方式处理请求。

在做COUNT时,服务器只会分配内存来存储计数的结果。

使用mysql_num_rows时,服务器会处理整个结果集,为所有结果分配内存,并将服务器置于获取模式,这涉及到很多不同的细节,例如锁定。

把它想象成下面的伪场景:

SELECT COUNT(*)

嗨,鲍勃,教室里有多少人?

mysql_num_rows

嘿,鲍勃,把教室里的所有人都给我送过来,……我自己数一数,得到人数

总而言之,当使用mysql_num_rows 时,您会将所有记录传输给客户端,而客户端必须自己计算计数。

【讨论】:

如果结果中有 1m 行怎么办?内存不是问题。问题是什么会更快? 现在关于我的问题:鲍勃已经给了我所有人的名单。我应该问鲍勃教室里有多少人吗?还是我应该使用他给我的清单并计算我自己? 如果您已经拥有数据,那么执行 num_rows 会更快(因为您没有进行其他查询),但您说您正在使用分页,num_rows 也是如此将是分页结果集的限制,而不是总数? 我从 DB 得到了一些结果。我每页有 10 个结果。所以我需要计算页面总数(计数(结果)/10)并生成导航链接。因为我已经有来自数据库的数据,所以我问我是否应该使用 (count($query_again)/10) of (mysql_num_rows(results)/10) 我这样做的方式是有两个查询。第一次查询获取总数,然后第二次查询使用LIMIT x OFFSET y获取分页数据。【参考方案3】:

inoDB 引擎和 mysql 5.5 中测试。

id 有索引,我认为这非常快

$q = "SELECT count(`id`) FROM table where 1";
$rows = mysql_query($q);
$count = mysql_fetch_array($rows);
echo $count[0];

如果您想要更多,您必须在 id 或您想要选择的任何内容上使用一个索引。

缓存是另一种解决方案,您可以在几毫秒内从一组记录中进行选择!

【讨论】:

以上是关于SELECT COUNT() 与 mysql_num_rows();的主要内容,如果未能解决你的问题,请参考以下文章

Mysql 用SELECT count(*)效率高还是SELECT count(1)效率更高?

SELECT COUNT() 与 mysql_num_rows();

select count(*)countcount的区别和执行效率比较

select count() , select count和select count(keyId)优化如何选择

[真伪]数据库中 select count(1) 比 select count(*) 快?

Cassandra 中的 COUNT(*) 与 COUNT(1) 性能