Warum muss Magento alle Beschriftungen aus dem Universum laden, um Farbfelder zu erstellen?

7

Ich arbeite an einem Geschäft mit 23.000 möglichen Farbwerten. Aber sie werden natürlich nicht bei jedem Produkt verwendet.

Jetzt, da wir an 1.9.2.1 arbeiten, das native Farbfelder enthält, dauert das Laden der Produktseite 3 Minuten.

Dies liegt daran , dass die _loadOptionLabels- Methode von Mage_ConfigurableSwatches_Model_Resource_Catalog_Product_Attribute_Super_Collection bei jedem Laden einer einzelnen Produktseite alle 23.000 Farben lädt.

Hat jemand das gleiche Problem oder weiß er, wie man es optimiert?

Ich habe auch versucht, alle nicht verwendeten Optionswerte zu bereinigen , aber das Laden und Verwenden von Resource_Iterator zur Beschleunigung von foreach dauert immer noch so lange, hat aber nicht funktioniert. Das Problem ist die große Frage.

Ricardo Martins
quelle
Ich kann nicht mit "Warum" antworten, aber wir sind auch auf einer Website mit einigen 2k-Farboptionen darauf gestoßen. Die Katalogansichten dauerten aufgrund der Farbfelder mindestens eine Minute. Wir haben das Modul aufgrund seines nicht optimierten Status vollständig deaktiviert und eine benutzerdefinierte Lösung entwickelt.
Ryan Hoerr

Antworten:

7

Ich habe ein Modul erstellt, um \ Mage_ConfigurableSwatches_Model_Resource_Catalog_Product_Attribute_Super_Collection :: _ loadOptionLabels folgendermaßen zu überschreiben:

protected function _loadOptionLabels()
{
    if ($this->count()) {

        $attributeIds = array();
        $productId = false;
        $filterLabels = false;
        foreach ($this->_items as $item) {
            $attributeIds[] = $item->getAttributeId();
            $id = $item->getProductId();
            $productId[$id] = $id;
        }
        if (is_array($productId) && $attributeIds) {
            $filterLabels = true;
        }

        if ($filterLabels) {
            $productIntTable = 'catalog_product_entity_int';
            $select = $this->getConnection()->select()
                ->from(array('l' => $this->getTable('catalog/product_super_link')), array('i.value'))
                ->join(
                    array('i' => Mage::getSingleton('core/resource')->getTableName($productIntTable)),
                    'i.entity_id = l.product_id'
                )
                ->where('l.parent_id IN (?)', array_keys($productId))
                ->where('i.attribute_id IN (?)', $attributeIds);
            $optionIdsToSelect = $this->getConnection()->fetchCol($select);
        }


        $select = $this->getConnection()->select()
            ->from(
                array('attr' => $this->getTable('catalog/product_super_attribute')),
                array(
                    'product_super_attribute_id' => 'attr.product_super_attribute_id',
                )
            )
            ->join(
                array('opt' => $this->getTable('eav/attribute_option')),
                'opt.attribute_id = attr.attribute_id',
                array(
                    'attribute_id' => 'opt.attribute_id',
                    'option_id' => 'opt.option_id',
                )
            )
            ->join(
                array('lab' => $this->getTable('eav/attribute_option_value')),
                'lab.option_id = opt.option_id',
                array(
                    'label' => 'lab.value',
                    'store_id' => 'lab.store_id',
                )
            )
            ->where('attr.product_super_attribute_id IN (?)', array_keys($this->_items));

        if ($filterLabels) {
            $select->where('opt.option_id IN (?)', $optionIdsToSelect);
        }
        $result = $this->getConnection()->fetchAll($select);
        Mage::getSingleton('core/resource_iterator')->walk(
            $select,
            array(function($args){
                $data = $args['row'];
                $item = $this->getItemById($data['product_super_attribute_id']);
                if (!is_array($labels = $item->getOptionLabels())) {
                    $labels = array();
                }
                $labels[$data['option_id']][$data['store_id']] = $data['label'];
                $item->setOptionLabels($labels);
            })
        );

    }
    return $this;
}

Ich habe die Abfrage gefiltert und foreach durch einen Iterator ersetzt.

Es bringt mir jetzt ungefähr 24 bis 40 Datensätze pro Produkt, stattdessen 23.000. :) :)

Dieses Modul führt auch unnötige Aufrufe der Produktliste durch, wenn Sie nicht eingerichtet sind, um etwas in der Produktliste anzuzeigen. Möglicherweise muss Mage_ConfigurableSwatches_Model_Observer :: productListCollectionLoadAfter neu geschrieben werden, um zu überprüfen, ob configswatches / general / product_list_attribute ein zu ladendes Attribut hat.

Ricardo Martins
quelle