2

我们的 Magento 安装有一个主页块,它显示来自给定类别的随机选择的产品。它有效,但它真的很慢。我将罪魁祸首追踪到以下功能:

protected function _getProductCollection()
{
    if (is_null($this->_productCollection))
    {
        $categoryID = $this->getCategoryId();
        if($categoryID)
        {
            $category = new Mage_Catalog_Model_Category();
            $category->load($categoryID);
            $collection = $category->getProductCollection();
        }
        else
        {
            $collection = Mage::getResourceModel('catalog/product_collection');
        }
        Mage::getModel('catalog/layer')->prepareProductCollection($collection);

        if ($this->getIsRandom())
        {
            $collection->getSelect()->order('rand()'); // REALLY slow, approx 4000ms at 25k products
        }

        $collection->addStoreFilter();
        $productCount = $this->getProductCount() ? $this->getProductCount() : 8;
        $collection->setPage(1, $productCount)
            ->load();

        $this->_productCollection = $collection;
    }
    return $this->_productCollection;
}

具体来说,这是非常$collection->getSelect()->order('rand()');慢的语句,在我们当前的产品计数约为 25k 时,我们的第一个字节的时间增加了大约 4000 毫秒。只需禁用随机性即可将我们的页面加载时间缩短约 3700 毫秒。

我想在应用程序级别执行随机化,而不是使用众所周知的慢 MySQLORDER BY RAND()方法。我尝试应用在主页 magento 上的 Randomise & limit Category thumbs 中描述的方法,具体更改:

$collection->getSelect()->order('rand()');

进入这个(及其变化的排列):

$collection->getSelect()->addIdFilter(array_rand(array_flip($category->getAllChildren(true)),5));

效果是现在该块根本没有显示在前端。我将不胜感激有关如何实现上面链接的解决方案的任何建议,或者任何其他有效的方法来随机化上面引用的$collection变量。

4

1 回答 1

0

这是上述问题的有效解决方案;这使用了应用程序,而不是数据库级别的随机化,并且确实对 Magento 的 time-to-first-byte 产生了显着的改进。

function _getProductCollection()
{

    if (is_null($this->_productCollection)) {
        $categoryID = $this->getCategoryId();
        if ($categoryID) {
            $category = new Mage_Catalog_Model_Category();
            $category->load($categoryID);
            $collection = $category->getProductCollection();
        } else {
            $collection = Mage::getResourceModel('catalog/product_collection');
        }

        Mage::getModel('catalog/layer')->prepareProductCollection($collection);

        $maxsize = $collection->getSize();
        $randArray = array();
        while (count($randArray) <= 50) {
            $randArray[] = rand(1, $maxsize);
        }

        if ($this->getIsRandom()) {
            $collection->getSelect()->where('product_id IN (?)',$randArray)->order('RAND()');
        }

        $collection->addStoreFilter();
        $productCount = $this->getProductCount() ? $this->getProductCount() : 8;
        $collection->setPage(1, $productCount)->load();

        $this->_productCollection = $collection;
    }
    return $this->_productCollection;

}
于 2013-12-03T12:22:08.327 回答