【发布时间】:2016-09-28 00:16:12
【问题描述】:
这与之前的问题有关:Doctrine/Symfony query builder add select on left join
我想使用 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
【问题讨论】:
-
你能用 KNP-Paginator 吗?
标签: php mysql symfony doctrine-orm pagination