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-1
和 total_rows=total_rows1+1
在 DELETE
和 INSERT
期间)。
但问题是如何处理搜索结果的分页?
现在我分两步进行:
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)优化如何选择