即使对于部分结果集,Symfony对象的水合作用也太慢

时间:2019-07-29 07:42:50

标签: php doctrine symfony-2.7

我有一个Symfony应用程序,正在从数据库中获取结果。尽管我只有5,000个结果集,但Doctrine大约需要16秒才能将结果恢复。经过更多研究后,我发现查询实际上运行非常快,仅需1.5秒,但补水时间为15秒。

我有一个对象查询,并且正在使用部分结果集。我的查询如下所示。

我知道,如果我要使用数组结果,查询会更快,但是从此查询中获取结果后,我的功能太复杂了,并且是基于从查询中获取对象格式而构建的。

$query = $this->getEntityManager()->createQueryBuilder();

        $query->select('v', 'dca','ca', 'c', 'vt', 'i', 'e', 
            'b', 'f','a','d','lc','fc','lcl','orc','nvo', 'ostatus','ot',
            'lcsi', 'fcsi', 'lclsi', 'orcsi', 'lcs', 'fcs', 'lcls', 'orcs',
            'country', 'ccp', 'acp', 'ccpu', 'acpu'
        )
            ->from('CoreBundle:Vehicle', 'v')

            ->leftjoin('v.vehicleCostAllocation', 'dca', 'WITH', '(dca.dateActive <= :currdate AND dca.dateInactive >= :currdate)
                            OR (dca.dateActive <= :currdate AND dca.dateInactive IS NULL)'
            )->setParameter('currdate', date('Y-m-d'))

            ->leftjoin('dca.costAllocation', 'ca')

            ->leftjoin('ca.contactPerson', 'ccp')
            ->leftjoin('ccp.user', 'ccpu')

            ->leftjoin('v.company', 'c')
            ->leftjoin('v.vehicleType', 'vt')
            ->leftjoin('v.incomeTaxAddition', 'i')
            ->leftjoin('v.energyLabel', 'e')
            ->leftjoin('v.brand', 'b')
            ->leftjoin('v.fuelType', 'f')
            ->leftjoin('v.replacementVehicleOrder', 'nvo')
            ->leftjoin('v.ownershipType', 'ot')
            ->leftjoin('nvo.orderStatus', 'ostatus')
            ->leftjoin('v.allocation', 'a', 'WITH', '(a.dateStart <= :currDate AND a.dateEnd >= :currDate)
                    OR (a.dateStart <= :currDate AND a.dateEnd IS NULL)'
            )->setParameter('currDate', date('Y-m-d'))
            ->leftjoin('a.driver', 'd')

            ->leftjoin('a.contactPerson', 'acp')
            ->leftjoin('acp.user', 'acpu')

            ->leftjoin('v.leaseContract', 'lc', 'WITH', '(lc.deleted IS NULL)')
            ->leftjoin('lc.contractState', 'lcsi')
            ->leftjoin('lc.supplier', 'lcs')

            ->leftjoin('v.fuelContract', 'fc', 'WITH', '(fc.deleted IS NULL)')
            ->leftjoin('fc.contractState', 'fcsi')
            ->leftjoin('fc.supplier', 'fcs')

            ->leftjoin('v.leaseContractLimited', 'lcl', 'WITH', '(lcl.deleted IS NULL)')
            ->leftjoin('lcl.contractState', 'lclsi')
            ->leftjoin('lcl.supplier', 'lcls')

            ->leftjoin('v.onRentContract', 'orc', 'WITH', '(orc.deleted IS NULL)')
            ->leftjoin('orc.contractState', 'orcsi')
            ->leftjoin('orc.supplier', 'orcs')

            ->leftjoin('v.country', 'country')

            ->where('c.id =:companyId')->setParameter('companyId', $companyId)

            ->andWhere('v.deleted IS NULL')
            ->orderBy('v.id', 'DESC')
        ;

        if ($userCostAllocations!==false && count($userCostAllocations)>0) {
            $query->andWhere('ca.id IN ('.implode(", ", $userCostAllocations).')');
        }

        $this->appendVehicleTypesConditions($query, $displayTypes);

        if ($showActive!==false) {   
            //$query->andWhere('v.status IN (1, 2)');           
            $query->andWhere('v.status IN (:vstatus)')->setParameter('vstatus', $showActive);

            $query->orderBy('v.licensePlate', 'ASC');
        }

        if ($vehicleId !== false && $vehicleId > 0) {

            $query->andWhere('v.id = :vehicleId')->setParameter('vehicleId', $vehicleId);
        }

        //To only get results from query that are in join, no extra queries run automatically
        $newQuery = $query->getQuery();
        $newQuery->setHint($newQuery::HINT_FORCE_PARTIAL_LOAD, true);

        //return $query->getQuery()->getResult();
        return $newQuery->getResult();

有人对改进有任何建议吗? 我进行了很多研究,但找不到更快的方法。

0 个答案:

没有答案