这与之前的问题有关:Doctrine/Symfony 查询生成器在左连接上添加选择 https://stackoverflow.com/questions/39721673/doctrine-symfony-query-builder-add-select-on-left-join?noredirect=1#comment66743717_39721673
我想使用 Doctrine ORM 执行复杂的联接查询。我想选择 10 篇分页博客文章,左侧加入单个作者,例如当前用户的价值以及文章上的主题标签。我的查询生成器如下所示:
$query = $em->createQueryBuilder()
->select('p')
->from('Post', 'p')
->leftJoin('p.author', 'a')
->leftJoin('p.hashtags', 'h')
->leftJoin('p.likes', 'l', 'WITH', 'l.post_id = p.id AND l.user_id = 10')
->where("p.foo = bar")
->addSelect('a AS post_author')
->addSelect('l AS post_liked')
->addSelect('h AS post_hashtags')
->orderBy('p.time', 'DESC')
->setFirstResult(0)
->setMaxResults(10);
// FAILS - because left joined hashtag collection breaks LIMITS
$result = $query->getQuery()->getResult();
// WORKS - but is extremely slow (count($result) shows over 80,000 rows)
$result = new \Doctrine\ORM\Tools\Pagination\Paginator($query, true);
奇怪的是,分页器上的 count($result) 显示了我的表中的总行数(超过 80,000),但使用 foreach 遍历 $result 输出了 10 个 Post 实体,正如预期的那样。我需要做一些额外的配置来正确限制我的分页器吗?
如果这是分页器类的限制,我还有什么其他选择?编写自定义分页器代码或其他分页器库?
(奖励):如何水合数组,例如 $query->getQuery()->getArrayResult();?
编辑:我在函数中遗漏了一个杂散的 orderBy 。看起来同时包含 groupBy 和 orderBy 会导致速度减慢(使用 groupBy 而不是分页器)。如果我省略其中之一,查询就会很快。我尝试在表中的“时间”列上添加索引,但没有看到任何改进。
我尝试过的事情
// works, but makes the query about 50x slower
$query->groupBy('p.id');
$result = $query->getQuery()->getArrayResult();
// adding an index on the time column (no improvement)
indexes:
time_idx:
columns: [ time ]
// the above two solutions don't work because MySQL ORDER BY
// ignores indexes if GROUP BY is used on a different column
// e.g. "ORDER BY p.time GROUP BY p.id is" slow