如果我使用COUNT查询而不是在Symfony 4中循环访问实体,是否会获得更好的性能?

时间:2019-02-21 09:49:17

标签: php performance symfony orm doctrine

例如,我需要获取评论数,一种方法是这样的:

public function getActiveReviews()
{
    return $this->getReviews()->filter(function(Review $review) {
        return $review->isActive() && !$review->isDeleted();
    })->count();
}

另一种方法是使用查询生成器,如下所示:

$qb = $this->createQueryBuilder('r')
      ->where('r.active = true')
      ->andWhere('r.deleted = false')
      ->select('count(r)')

哪种方法可以给我带来更好的性能,为什么?

2 个答案:

答案 0 :(得分:4)

当然,计数查询会更快,因为它会导致返回单个值的单个SQL查询。

实体迭代需要:

  1. 运行SQL查询以获取数据行
  2. 实际获取数据
  3. 实体对象实例化并将获取的数据持久化到其中

取决于受影响的数据量,差异可能很大。

运行计数实体时可能唯一足够快的情况是,已经获取了所有实体并且只需要对它们进行计数。

答案 1 :(得分:1)

这取决于Symphony count()的实现,但您可能会这样做。通常,RDBMS在内部更快地对其行进行计数,并且需要更少的资源。

在第一种情况下,您请求一个完整的行集,该行集可能很大,然后对其进行迭代,将过滤器函数应用于每一行,然后仅查看过滤后的行集大小并删除所有内容。 (但是,当然,您的框架可能会对此进行优化)。

在第二种情况下,您只是问数据库有多少行满足条件。然后DB返回一个数字,仅此而已。

正如其他人所说,唯一的选择可能是更快的选择,那就是当您已经缓存了行集(无需连接到数据库)时-同时您的数据库连接非常慢。

我看到在大表上某些COUNT请求(Oracle)上的数据库运行缓慢,但仍比同一行集中的PHP代码要快。数据库针对数据过滤和计数进行了优化。通常,COUNT个请求非常快。