如果我在 Symfony 4 中使用 COUNT 查询而不是遍历实体,我会获得更好的性能吗?

Posted

技术标签:

【中文标题】如果我在 Symfony 4 中使用 COUNT 查询而不是遍历实体,我会获得更好的性能吗?【英文标题】:Will I get better performance if I use COUNT query instead of looping through entities in Symfony 4? 【发布时间】:2019-02-21 09:49:17 【问题描述】:

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

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)')

哪种方式会给我带来更好的性能,为什么?

【问题讨论】:

这是一个老的但很好的答案,它稍微改进了您的 count(r) 查询以返回单个标量计数,从而提高性能一点点。 ***.com/questions/9214471/… 是的,使用数据库会快很多倍,除非您已经需要其他内容的评论。 【参考方案1】:

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

对实体的迭代需要:

    运行用于获取数据行的 SQL 查询 实际获取数据 实体对象实例化并将获取的数据持久化到其中

根据受影响的数据量,差异可能非常大。

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

【讨论】:

【参考方案2】:

这取决于 Symfony count() 的实现,但你可能会。通常 RDBMS 在内部更快地计算其行数,并且它需要的资源要少得多。

在第一种情况下,您请求一个可能很大的整个行集,然后遍历它,将过滤器功能应用于每一行,然后您只需查看过滤后的行集大小并删除所有内容。 (当然,这可能会被您的框架以某种方式优化)。

在第二种情况下,您只需询问数据库满足条件的行数。 DB 会返回一个数字,仅此而已。

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

我看到数据库在大表上的一些 COUNT 请求 (Oracle) 上速度很慢,但它们仍然比同一行集上的 php 代码快。 DB针对数据过滤和计数进行了优化。而且通常 COUNT 请求非常快。

【讨论】:

以上是关于如果我在 Symfony 4 中使用 COUNT 查询而不是遍历实体,我会获得更好的性能吗?的主要内容,如果未能解决你的问题,请参考以下文章

无法安装探查器symfony flex

在 Symfony 4.4 中使用 RedisTagAwareAdapter

Symfony 4 在 Windows 上非常慢

在 Symfony 4.4 中使用注解测试控制器

Symfony:如何处理表单中的日期字段

Symfony 4 会话过期太快