简体   繁体   English

Symfony 使用 queryBuiler 并了解性能

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM