[英]Symfony with queryBuiler and understanding performance
I have a query that returns a single product with its relationships.我有一个返回单个产品及其关系的查询。 I want this page to load fast, so query performance is very important for me.
我希望此页面加载速度快,因此查询性能对我来说非常重要。 However, I am having big performance issues and I don`t really understand how this could be fixed in Symfony.
但是,我遇到了很大的性能问题,我真的不明白如何在 Symfony 中解决这个问题。
This is my query:这是我的查询:
public function findProduct(string $id, string $locale)
{
$dateNow = date('Y-m-d') . ' 23:59:59';
$qb = $this->createQueryBuilder('p');
$qb->innerJoin('p.productRegionData', 'prd');
// $qb->addSelect('prd');
$qb->innerJoin('prd.region', 'r', 'WITH', "r.iso = '" . $locale . "'");
$qb->leftJoin('p.productCategories', 'pc');
// $qb->addSelect('pc');
$qb->innerJoin('p.productSeoUrls', 'psu');
// $qb->addSelect('psu');
$qb->leftJoin('p.productDiscounts', 'pd', 'WITH', "pd.active = 1 AND pd.discountFrom <= '" . $dateNow . "' AND pd.discountTo >= '" . $dateNow . "'");
// $qb->addSelect('pd');
$qb->leftJoin('p.productWallThicknesses', 'pwt');
// $qb->addSelect('pwt');
$qb->innerJoin('p.productImages', 'pi');
// $qb->addSelect('pi');
$qb->leftJoin('p.productFloorDimensions', 'pfd');
// $qb->addSelect('pfd');
$qb->leftJoin('p.productWindows', 'pw');
// $qb->addSelect('pw');
$qb->leftJoin('p.productDoors', 'pdo');
// $qb->addSelect('pdo');
$qb->leftJoin('p.productAttributes', 'pa');
// $qb->addSelect('pa');
$qb->leftJoin('pa.attribute', 'at');
// $qb->addSelect('at');
$qb->andWhere('p.id = :id');
$qb->setParameter('id', $id);
$qb->groupBy('p');
return $qb->getQuery()->getOneOrNullResult();
}
As you can see this query returns a product with multiple relationships.如您所见,此查询返回具有多个关系的产品。 Now there are 3 scenarios that I have tried and each of them solves one problem, but another problem occurs.
现在我尝试了 3 种方案,每种方案都解决了一个问题,但又出现了另一个问题。
SCENARIO 1: Using groupBy
without addSelect()
.场景 1:在不使用
addSelect()
的情况下使用groupBy
。
This is the fastest in terms of performance, however each time I access a relationship, a new query is excecuted(if I understand that is because I am not using addSelect()
and thats how Doctrine works).这在性能方面是最快的,但是每次我访问一个关系时,都会执行一个新查询(如果我明白那是因为我没有使用
addSelect()
并且这就是 Doctrine 的工作原理)。 This is pretty quick, however I am concerned with the large amount of queries being executed for a single product:这非常快,但是我担心为单个产品执行的大量查询:
SCENARIO 2: Not using groupBy
and using addSelect()
场景 2:不使用
groupBy
而使用addSelect()
Performance wise this scenario is the slowest because I am running out of php memory(its 128MB but it still shouldn t take that much?). However the number of queries is reduced drastically since I am using
在性能方面,这种情况是最慢的,因为我用完了 php 内存(它是 128MB,但它仍然不应该
t take that much?). However the number of queries is reduced drastically since I am using
t take that much?). However the number of queries is reduced drastically since I am using
addSelect()` t take that much?). However the number of queries is reduced drastically since I am using
SCENARIO 3: Using groupBy
and using addSelect()
场景 3:使用
groupBy
和使用addSelect()
The fastest solution in terms of performance, however, using this will return a single entity from a relationship.然而,就性能而言,这是最快的解决方案,使用它将从关系中返回单个实体。 For example if I have 5 images, it will return only 1 image, which is of course not what I want.
比如我有5张图片,它只会返回1张图片,这当然不是我想要的。
So now I am really struggling to understand how this should be achieved in the best way?所以现在我真的很难理解如何以最好的方式实现这一点? Which scenario is the best, maybe there is a better one?
哪种方案最好,也许有更好的方案? Maybe I should just use raw sql?
也许我应该只使用原始 sql? Any help is appreciated.
任何帮助表示赞赏。
You don't have a relation between all these tables?您没有所有这些表之间的关系?
Your query is restarting in a loop.您的查询正在循环中重新启动。
Are you just selecting from the same table?你只是从同一张表中选择吗? I don't understand your inner join syntax.
我不明白你的内部连接语法。
<?php
$queryBuilder
->select('u.id', 'u.name', 'p.number')
->from('users', 'u')
->innerJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.