Php PDO::行数VS计数(*)

Php PDO::行数VS计数(*),php,mysql,optimization,pdo,Php,Mysql,Optimization,Pdo,我有一个使用PDO的查询,首先计算行数,如果行数大于1,则先获取数据 SELECT * WHERE id=:id $row=$SQL->rowCount(); if($row>0){ while($data=$SQL->fetch(PDO::FETCH_ASSOC)){... } } else{echo "no result";} 或 哪个性能更好 第二。问题,我是否已经在id上设置了索引 哪一个更好COUNT(id)或COUNT(*)性能差异应该可以忽略

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

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

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

    }
}
else{echo "no result";}

哪个性能更好

第二。问题,我是否已经在id上设置了索引


哪一个更好
COUNT(id)
COUNT(*)

性能差异应该可以忽略不计为null,因为在这两种情况下您只发出一个查询。第二个查询必须为匹配
id
的每一行获取一个具有相同值的额外列,因此它可能会占用大量内存。即使没有
计数(*)
行计数也应该可用,因此您应该使用第一种解决方案

关于第二个问题,AFAIK无论是
COUNT(id)
还是
COUNT(*)
都会在
id
上使用索引更快,因为db引擎必须执行范围扫描来检索有问题的行,而在索引列上进行过滤时,使用索引进行范围扫描更快(在您的情况下
id=SOME\u id
).

Count(id)或Count(*)将使用索引扫描,因此性能会更好。Rowcount仅返回受影响的行,在插入/更新/删除时非常有用

编辑:
由于该问题被编辑为比较Count(id)和Count(),因此会产生轻微的差异。Count()将返回受select影响的行数。Count(column)将返回非null值Count,但由于它是id,所以不会有null列。所以对这个案例来说没有什么区别。

第一个问题:

使用count
count()
,服务器(MySQL)内部将以不同的方式处理请求

当执行
COUNT()
时,服务器(MySQL)将只分配内存来存储计数结果

使用
$row=$SQL->rowCount()时服务器(Apache/PHP)将处理整个结果集,为所有这些结果分配内存,并将服务器置于获取模式,这涉及许多不同的细节,例如锁定

请注意,
PDOStatement::rowCount()
返回受上一条语句影响的行数,而不是返回的行数。如果关联的
PDOStatement
执行的最后一条SQL语句是
SELECT
语句,则某些数据库可能会返回该语句返回的行数。但是,并非所有数据库都能保证这种行为,便携式应用程序也不应依赖这种行为

根据我的分析,如果使用
COUNT()
,进程将同时被划分为MySQL和PHP,而如果使用
$row=$SQL->rowCount(),处理将更适合PHP

因此,MySQL中的
COUNT()
更快

第二个问题:

COUNT(*)
优于
COUNT(id)

说明:

mysql中的
count(*)
函数经过优化以查找值的计数。使用通配符意味着它不会获取每一行。它只能找到伯爵。因此,尽可能使用
count(*)

来源:

计数(*)
会更快

根据PDO文档,
PDOStatement::rowCount()
不保证工作正常:

“并非所有数据库都能保证,便携式应用程序也不应依赖。”

因此,在您的情况下,我建议使用
count(*)

见参考资料:

事实上,这里不需要PDO ROWCUNT或COUNT(*)。

如果行>1,则获取数据

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

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

    }
}
else{echo "no result";}
是错误的陈述。
在一个设计合理的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";
}
请注意,您不应选择超过需要的行。意味着您在常规网页上的查询不应返回超过显示的行数

说到这个问题本身,它毫无意义。人们无法将
rowCount
COUNT(*)
进行比较,因为这是无法比拟的事情。这两种功能的用途完全不同,不能互换:

  • COUNT(*)
    返回带有COUNT的一行,并且只有在需要记录计数时才必须使用,但没有记录本身
    如果您需要记录,
    count(无论什么)
    既不快也不慢,它是毫无意义的。
  • rowCount()

更不用说第二个示例根本不会获取任何行。

注意:对于select语句,并非所有数据库都会通过
PDO::rowCount
返回行计数,而严格的iirc MySQL会这样做。SQL语句不会达到预期效果,请删除第二个星型
select count(*)在tablename中,id=:id
@martinstoeckli,这个语句是正确的。问题中唯一的陈述though@YourCommonSense-在我的理解中,
count(*)
总是返回1(或0),因为第二颗星总是返回唯一的行,所以它没有意义。但是正如你正确地指出的,如果问题仅仅是一行是否存在,它就会起作用