php - Symfony2、PHP 在统计数据库中的许多对象时减少查询权重

标签 php mysql symfony

所以我的数据库中有 4 个表。产品、类别、产品类别和产品子类别。

这些表处于多对多关系中。

所有产品都保存在表:产品中。

所有类别和子类别都保存在一张表中:类别。

产品可以有子类别但没有类别,可以同时拥有两者,或者可以有类别但没有任何子类别。

ProductCategory 和 ProductSubcategory 保存着所有关系。(product_id 和category_id/subcategory_id)

现在,在我的 Twig 中,我想计算该类别和子类别包含多少产品。为此,我使用 Twig Extensions。

对于子类别:

计算子类别中有多少产品很简单而且有效。

在 Twig 中:

{% for subcategory in categories.children %}

     [{{ getProductsBySubcategory(subcategory.id) }}]

{% endfor %}

功能:

public function getProductsBySubcategory($id)
    {
    $products = 0;

    $subcategories = $this->doctrine->getRepository('MpShopBundle:ProductSubcategory')->findBy(array('subcategory' => $id));

    foreach ($subcategories as $subcategory) {
        $products++;
    }

    return $products;

    }

对于类别:

对于类别来说有点不同。这里我想统计该类别下的所有产品以及该类别下的所有子类别中的产品。首先,我检查该类别是否有产品,如果有,我将其添加到数组中。然后我检查这个类别是否有子类别。如果是这样,我会从子类别中获取所有产品并将它们添加到同一个数组中。现在,如果产品既属于类别又属于子类别,我不想重复计算。这就是为什么我将所有内容存储在数组中(稍后执行 array_unique 操作)。

我的 Twig :

[{{ getProductsByCategory(categories.id)|length }}]

功能:

public function getProductsByCategory($id)
    {
    $category = $this->doctrine->getRepository('ApplicationSonataClassificationBundle:Category')->find($id);
    $productCategories = $this->doctrine->getRepository('MpShopBundle:ProductCategory')->findBy(array('category' => $id ));
    $productSubcategories = $this->doctrine->getRepository('MpShopBundle:ProductSubcategory')->findAll();
    $products = array();

    foreach($productCategories as $productCategory) {

        array_push($products, $productCategory->getProduct()->getId());
    }

    foreach($productSubcategories as $productSubcategory) {

       $subcategory = $productSubcategory->getSubcategory();

        if($subcategory->getparent() == $category) {
            array_push($products, $productSubcategory->getProduct()->getId());
        }

    }
        $result = array_unique($products);

    return $result;

    }

问题:

一切都在本地运行。我得到了正确的号码。但是,当我切换到 Live 时,我收到错误:500。我想这可能是因为Live有数千种产品和分配的类别。所以 foreach 循环正在破坏服务器。或者也许是因为我将所有内容保存在数组中?

我该怎么办?是不是服务器的问题,我需要增加一些东西?或者也许有一种方法可以在不使用数组和减少循环计数的情况下进行计数?但是如何检查重复项呢?

日志显示:

Allowed memory size of 536870912 bytes exhausted (tried to allocate 77 bytes) in /var/www/kd_cms/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php on line 40

最佳答案

对于大型数据库对象,Dql 比 foreach 更快

// .../ProductCatRepository.php
public function findDistinctProductsByCat($catId)
{
   $query = $this->createQueryBuilder('entity')
        ->leftjoin('entity.category', 'cat')  
        ->andWhere('cat.id = :cat')
        ->setParameter('cat', $catId)
    ;
    return $query->getQuery()->getResult();
}

// .../ProductSubCatRepository.php
public function findDistinctProductsByCatSubCat($catId)
{
   $query = $this->createQueryBuilder('entity')
        ->leftjoin('entity.subcategory', 'subcat') 
        // maybe missing a leftJoin with cat idk your mapping
        // ->leftJoin('subcat.category', 'cat')
        // ->andWhere('cat.parent = :cat')
        ->andWhere('subcat.parent = :cat')
        ->setParameter('cat', $catId)
    ;
    return $query->getQuery()->getResult();
}


public function getProductsByCategory($id)
{
$categoryId = $id; 

$productsCat = $this->doctrine->getRepository('MpShopBundle:ProductCat')->findDistinctProductsByCat($categoryId);
$productsSubCat = $this->doctrine->getRepository('MpShopBundle:ProductSubCat')->findDistinctProductsByCatSubCat($categoryId);
// ArrayCollection::count()

return array('count_cat' => $productsCat->count(), 'product_subcat' =>    $productsSubCat->count(), 'result' => array_unique(array_merge($productsSubCat, $productsCat)));
}

关于php - Symfony2、PHP 在统计数据库中的许多对象时减少查询权重,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33210480/

相关文章:

php - 处理超大阵列的最佳实践? D B?

php - 在 firestore (php) 中增加一个字段

mysql - 如何在 MySQL 中选择文件名的子字符串?

PHP & MySQL checked checkbox 问题

php - JMSSerializer 和 FOSRestBundle - 注释不起作用。 "Does not exist"

php - Symfony2 : How to disable form field on edit

php - Symfony 4.3.1 和 FosUserBundle 2.1.2 的问题

php - 解析图像 url(来自服务器)并将其存储到内部存储中的有效方法?

php - 为什么在 PDO 中使用 bindParam 而不用 array()?

mysql - 当两个表都包含 NULL 时如何加入