我有一个配置的 Doctrine QueryBuilder,我用它来为 API 响应创建一个列表。
此列表具有可变数量的
JOIN
和 WHERE
,具体取决于用户过滤/搜索的内容。
此查询不排序大约需要 1 秒,排序需要 10+秒,这太慢了。
在 SQL 中,我这样做了(我相信这称为 straight join),这解决了问题:
SELECT * FROM (
the-actual-build-query
)
ORDER BY delivery_date ASC
LIMIT 35
然而,我没有使用 SQL,而是 Doctrine QueryBuilder。但我不知道如何让 Doctrine 做同样的事情。 因为我正在使用准备好的语句,所以我不能只构建查询并包装它,我需要对参数做一些事情。但那些是各种各样的类型,我无法得到一个有效的优雅解决方案。
有人有可行的解决方案吗?
public function setSorting(QueryBuilder $qb): QueryBuilder
{
$stmt = $qb->getEntityManager()
->getConnection()
->prepare('SELECT * FROM (' . $qb->getQuery()->getSQL() . ') result');
foreach ($qb->getParameters() as $param) {
$stmt->bindValue(
$param->getName(),
$param->getValue(),
$param->getType() // <-- this fails on a binary uuid array
);
}
$result = $stmt->executeQuery();
return $finalQb;
}
我对纯 SQL 解决方案没问题。我更喜欢远离自定义参数转换/绑定(不,我对自己的解决方案不满意)。
// What I would like (pseudo code):
$newQB = createQueryBuilder();
$newQB
->addSelect('*') // or ->addSelect('inner')
->from($innerQb, 'inner')
->orderBy(inner.deliveryDate);
但是
from
或 addSelect
都无效。
$query = $qb->getEntityManager()
->createQuery('SELECT X FROM (' . $qb . ') as X')
->setMaxResults(10);
// "[Semantical Error] line 0, col 9 near 'FROM (SELECT': Error: Subquery is not supported here",
我对另一种解决方案也很好!