2013-01-18 67 views
1

我正在转换一个旧的mysql_X站点与PDO一起工作,到目前为止,这么好(我认为)。然而,我对计算查询结果的可靠性有疑问。使用count()来计算来自PHP中PDO的结果?

目前,我就拥有了一切准备像这样(我已经删除了try/catch语句错误代码,以使这更易于阅读):

$stm = $db->prepare("SELECT COUNT(*) FROM table WHERE somevar = '1'"); 
$stm->execute(); 
$count = $stm->fetchColumn(); 

if ($count > 0){ 
    $stm = $db->prepare("SELECT * FROM table WHERE somevar = '1'"); 
    $stm->execute(); 
    $result = $stm->fetchAll(); 
} 

有可能是愚蠢的问题,做这种方式,我邀请你告诉我是否有,但我的问题是关于减少数据库查询。我注意到,如果我先删除第一条语句,然后单独运行第二条语句,然后使用PHP的count()来计算结果,但我似乎仍然得到可靠的行数,只有一个查询,如下所示:

$stm = $db->prepare("SELECT * FROM table WHERE somevar = '1'"); 
$stm->execute(); 
$result = $stm->fetchAll(); 

$count = count($result); 
if ($count > 0){ 
    //do whatever 
} 

这样做有没有什么陷阱呢?它可靠吗?我的PDO有没有明显的错误?谢谢您的帮助!

+0

您是否试过'num_rows'? – Kermit

+0

我还没有试过num_rows。我已经尝试过rowCount,它也可以工作,但我已经读过,不建议在SELECT查询中使用它,因为结果可能并不总是可靠的。 – Marty

回答

2

在MySQL中进行计数是可取的,特别是如果计数值是您感兴趣的唯一结果。请将您的版本与同等问题“杂货店有多少巧克力棒存货?”进行比较。在db

1)计算:SELECT count(*) ....开车去商店,算上巧克力棒,记下号码,开车回家,阅读次数了你的论文

2)在PHP数:SELECT * ...。开车去商店。买所有的巧克力棒。把他们运回家。在你的客厅地板上数一数。将结果写在一张纸上。 扔掉巧克力棒。从纸上读取数字。

哪一种效率更高/成本更低?没有什么大不了的,如果你的db/table只有几条记录。当你开始达到数千/数百万条记录时,版本2)绝对是可笑的,可能会耗尽你的带宽,炸掉你的PHP内存限制,并将你的CPU使用率推到平流层。

这就是说,运行两个查询没有意义,一个只计算您可以获得多少条记录。这样的系统很容易受到竞争条件的影响。例如你做你的计数,并得到(说)1条记录。当你去运行第二个查询并获取该记录时,其他一些并行进程已经结束并插入另一个记录,或者删除了你想要的那个记录。

+0

我估计会有一个点,它会更有意义做计数的MySQL。在这种情况下,我正在使用的表格现在只有13个参赛作品,并且长时间不会变得非常大。在这种情况下,它也给我有用抢在一旦所有的结果 - 我会抓住反正他们所有,所以它不是一个巨大的损害服务器的两种方式。 – Marty

+0

这是一个很好的观察,虽然,我想我得记住这一点,因为我有在具有更多的条目同一个数据库的另一个表,而我将不得不限制使用更严格。谢谢! – Marty

0

在第一种情况下,您使用MYSQL计数,第二种情况下您使用PHP计数。两者都是相同的结果。

+0

是的,我意识到这一点。也许是有速度的权衡那里,我没有考虑到的画面......但现在,我在确保我得到可靠的结果,并限制数据库的查询数量最感兴趣时,我可以。 – Marty

+0

@Marty如果你只需要显示计数那么MySQL的方式最好是在速度方面,因为你不必再抓住所有的行知数。但是,如果你要显示他们都那么PHP的方式是更好的,因为你没有运行2个查询 –

+0

我都数不过来,然后在这种情况下显示结果,所以我认为这可能是最好在这里使用PHP的计数。感谢您的反馈! – Marty

0

您对查询的用法是正确的。当您使用LIMIT时,唯一的问题就会出现,因为COUNT(*)和count($ result)将会不同。

COUNT(*)将计算该查询将返回(假定计数查询是相同的,而不是用LIMIT)

计数($结果)的所有行会算刚刚返回的行,所以如果你使用LIMIT,你只会得到结果达到给定的极限。

+0

如果在两个查询中都使用LIMIT,结果将仍然相同。 –

+0

这就是为什么我说:“考虑到计数查询是相同的,而不是使用LIMIT” –

0

是的,它在这个用例中是可靠的!