pdo::行计数vs计数(*)

cotxawn7  于 2021-07-24  发布在  Java
关注(0)|答案(5)|浏览(400)

我有一个查询使用pdo,首先计算行数,如果行数大于1,则获取数据

SELECT * WHERE id=:id
$row=$SQL->rowCount();

if($row>0){
    while($data=$SQL->fetch(PDO::FETCH_ASSOC)){...

    }
}
else{echo "no result";}

SELECT COUNT(*), * WHERE id=:id
$data=fetch(POD::FETCH_NUM);
$row=data[0];

if($row>0){
//fetch data
}
else{echo "no result";}

哪个性能更好?
第二。问题是,我是否在id上设置了索引
哪一个更好 COUNT(id) 或者 COUNT(*)

g6baxovj

g6baxovj1#

第一个问题:
使用计数 COUNT() 在内部,服务器(mysql)将以不同的方式处理请求。
什么时候做 COUNT() ,服务器(mysql)将只分配内存来存储计数结果。
使用时 $row=$SQL->rowCount(); 服务器(apache/php)将处理整个结果集,为所有这些结果分配内存,并将服务器置于获取模式,这涉及许多不同的细节,例如锁定。
请注意 PDOStatement::rowCount() 返回受上一条语句影响的行数,而不是返回的行数。如果关联的 PDOStatement 是一个 SELECT 语句,某些数据库可能返回该语句返回的行数。但是,并非所有数据库都能保证这种行为,因此便携式应用程序不应依赖这种行为。
根据我的分析,如果你使用 COUNT() ,进程将被划分为mysql和php,而如果您使用 $row=$SQL->rowCount(); ,对php的处理会更复杂。
因此 COUNT() 在mysql中更快。
第二个问题: COUNT(*) 比…好 COUNT(id) .
说明:
这个 count(*) mysql中的函数被优化以查找值的计数。使用通配符意味着它不会获取每一行。它只能找到伯爵。所以使用 count(*) 只要可能。
资料来源:
PDO语句::行计数
mysql计数(*)

9lowa7mx

9lowa7mx2#

事实上,这里不需要pdo rowcount或count(*)。
如果行>1,则获取数据
是个错误的说法。
在一个设计合理的web应用程序中(我知道这听起来像是php的笑话),不必这样做。
最明智的办法是
先取
使用提取的数据
如果需要,我们可以使用这些非常获取的数据来查看是否返回了任何内容:

$data = $stmt->fetch();
if($data){
    //use it whatever
} else {
    echo "No record";
}

简单,直截了当,完全没有“哪个无用的特性更好”这样的问题。

在你的情况下,假设 id 是唯一索引,只能返回一行。因此,你不需要 while 一点声明都没有。只需使用上面的代码片段来获取和判断enythin是否已获取。
如果需要很多行,那么只需更改 fetch()fetchAll() 然后使用foreach迭代返回的数组:

$data = $stmt->fetchAll();
if($data){
    foreach ($data as $row) {
        //use it whatever
    }
} else {
    echo "No records";
}

请注意,您永远不要选择超过需要的行。意味着您在常规网页上的查询返回的行数不应超过显示的行数。
说到问题本身,这是毫无意义的。谁也比不上 rowCountCOUNT(*) 因为这是无与伦比的事情。这两种功能的用途完全不同,不能互换: COUNT(*) 返回一个带有count的单行,仅当需要记录的计数而不需要记录本身时才必须使用。
如果你需要记录, count(whatever) 既不快也不慢——毫无意义。 rowCount() 返回已经选定的行数,因此您几乎不需要它,如上所示。
更不用说第二个示例根本不会获取任何行。

tvokkenx

tvokkenx3#

count(id)或count(*)将使用索引扫描,这样性能会更好。rowcount只返回受影响的行,在插入/更新/删除时非常有用
编辑:由于问题被编辑为比较count(id)和count(),所以会有细微的差别。count()将返回受select影响的行计数。count(column)将返回非空值count,但因为它是id,所以不会有空列。所以这个案子没什么区别。

mqkwyuun

mqkwyuun4#

性能差异应该可以忽略到null,因为在这两种情况下您只发出一个查询。第二个查询必须为每个匹配的行获取一个具有相同值的额外列 id ,因此它可能会占用大量内存。即使没有 COUNT(*) 行计数应该是可用的,因此您应该使用第一个解决方案。
关于你的第二个问题 COUNT(id) 或者 COUNT(*) 索引打开会更快 id ,因为db引擎将必须执行范围扫描来检索有问题的行,并且范围扫描在索引列上进行筛选时使用索引会更快(在您的情况下) id = SOME_ID ).

fquxozlt

fquxozlt5#

Count(*) 会更快。 PDOStatement::rowCount() 不保证根据pdo文件工作:
“并非所有数据库都能保证,便携式应用程序不应依赖它。”
所以我建议你用 count(*) .
请参阅参考:pdostatement.rowcount手册

相关问题