Нужна помощь с отображением случайного кода товаров


Я хотел создать случайные продукты для определенных категорий на своей домашней странице. Наткнулся на этот код:

<?php
// $_productCollection = $this->getLoadedProductCollection();
 $_helper = $this->helper('catalog/output');
 $_category = Mage::getModel('catalog/category')->load($this->getCategoryId());
 $_productCollection = Mage::getResourceModel('reports/product_collection')
                   ->addAttributeToSelect('*')
                   ->addAttributeToFilter('small_image', array('neq' => 'no_selection'))
                   ->addCategoryFilter($_category)
                   ->setVisibility(array(2,3,4,5));
 $_productCollection->getSelect()->order(new Zend_Db_Expr('RAND()'));                  
 $_productCollection->setPage(1, 5);
?>

Теперь, когда я добавил его в свой измененный список.phtml, он не загружался. Играя вокруг единственного способа, которым я мог заставить вышеперечисленное работать, было поставить следующее ПЕРЕД приведенным выше кодом.

 <?php
$_productCollection=$this->getLoadedProductCollection();
$_productCollection->clear()
               ->addAttributeToFilter('small_image', array('neq' => 'no_selection'))
               ->setPageSize(5)
               ->load();
$_helper = $this->helper('catalog/output');
$this->setData('column_count',5); 
?>

Это работает, однако это приводит к замедлению загрузки страницы, на которой вызывается этот код. Я попытался изменить первый блок кода, чтобы включить элементы 2-го блока, но без костей.

Что можно изменить, чтобы сделать этот код более эффективным?

Author: Fabian Schmengler, 2014-08-24

1 answers

ORDER BY RAND() является неэффективным, поскольку это приводит к ресурсоемкой временной копии таблицы. Он должен загрузить все результаты во временную таблицу, присвоить каждой строке случайное число, а затем отсортировать без какого-либо индекса. Вместо этого мы извлекаем все идентификаторы кандидатов (это быстрее, и объем данных управляем даже для больших каталогов), выбираем некоторые случайным образом и извлекаем эти строки напрямую. Вы можете подробно прочитать об этом в моем блоге: http://www.schmengler-se.de/en/2015/09/show-random-products-in-magento-you-are-doing-it-wrong/

Для этого вставьте этот код после применения фильтров для коллекции:

$numberOfItems = 5;
$candidateIds = $_productCollection->getAllIds();
    $choosenIds = [];
    $maxKey = count($candidateIds)-1;
    while (count($choosenIds) < $numberOfItems)) {
        $randomKey = mt_rand(0, $maxKey);
        $choosenIds[$randomKey] = $candidateIds[$randomKey];
    }    
$_productCollection->addIdFilter($choosenIds);

Затем укажите только атрибуты, которые вам нужно загрузить вместо *, и соедините индексы цен и URL-адресов, если вы хотите показать правильную цену и URL-адрес продукта:

$_productCollection
    ->addMinimalPrice()
    ->addFinalPrice()
    ->addTaxPercents()
    ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
    ->addUrlRewrite();
 2
Author: Fabian Schmengler, 2015-09-29 13:18:04