Schnellster Weg, um zu überprüfen, ob Produkte vorhanden sind

7

Ich habe eine externe Datei mit Produktdetails. Ich durchlaufe diese Datei und muss für jedes Produkt in dieser Datei überprüfen, ob das Produkt bereits in Magento vorhanden ist.

Der Wert, der bewertet werden soll, ob das Produkt bereits vorhanden ist, ist ein Attributname und sein Wert.

Also überprüfe ich dies mit (pro Produkt)

$collection = Mage::getModel('catalog/product')
                ->getCollection()
                ->addAttributeToSelect('sku')
                ->addAttributeToSelect("$supplier_name")
                ->addAttributeToSelect('production_nr')
                ->addAttributeToSelect('sku_supplier')
                ->addAttributeToFilter($supplier_name,array('eq' => $suppliers_product_nr));

Diese Auswahl selbst scheint nicht viel Zeit in Anspruch zu nehmen:

            echo 'check: ',round(microtime(true) - $time, 2) , "s<br/>\n";

meldet 0,00 s,

Die Überprüfung, ob es sich um eine leere Sammlung handelt (dh das Produkt in meiner Magento-Datenbank vorhanden ist, dauert ca. 0,34 bis 0,40 Sekunden

$collection->getSize()

In Anbetracht dessen, dass ich mehrere hunderttausend Produkte überprüfen muss. Dies wird sich schnell summieren. Sehr schnell. Ich hatte auf etwas gehofft, das zeitlich eher 0,01 oder weniger entspricht.

Daher suche ich nach dem schnellsten Weg, um zu überprüfen, ob ein Produkt vorhanden ist. Ich habe einiges an Freiheit beim Ändern und Implementieren des Codes. Wenn es also eine völlig andere Art gibt, dieses Problem zu lösen, würde ich gerne davon hören.


Aktualisieren:

Ich habe es leicht geändert, damit ich nicht mit Magento prüfe, ob ein Produkt Produkt für Produkt vorhanden ist, sondern stattdessen eine Reihe aller Produkte erhalte, für die das Attribut geprüft werden muss. Ich benutze dieses Array, um zu überprüfen, ob das Attribut, gegen das geprüft werden soll, existiert.

Dies ist viel schneller, aber ich befürchte, dass dies Auswirkungen auf den Overhead (hauptsächlich RAM oder CPU) haben wird, wenn die Menge der zurückgegebenen Produkte zu groß wird (wir haben ungefähr 40.000 Produkte in unserer Magento-Installation).

Tropus
quelle
Bedeutet das nur zur Verdeutlichung, dass immer EIN Produkt für Ihre Auswahl zur Verfügung steht? Oder kann es mehrere Produkte geben, die zu dieser Kollektionsauswahl passen?
Raphael bei Digital Pianism
Die Quelldatei durchläuft jeweils nur ein Produkt (diese Produkte sind in der Datei eindeutig), aber die Sammlung kann mehrere Produkte in unserer Datenbank zurückgeben, die möglicherweise hinzugefügt wurden (ich kann nicht sagen, dass unsere Magento-Datenbank sehr sauber ist .)
Tropus
Verstehe ich Ihr Ziel richtig: Überprüfen Sie, ob das Produkt von sku existiert und einen geeigneten Attributwert hat? Welche Aktionen möchten Sie ausführen, wenn das Produkt vorhanden ist / nicht beendet wird?
Sergii Ivashchenko
Wenn ein Produkt nicht vorhanden ist, führt das Skript nichts aus und fährt mit dem nächsten Produkt fort. Wenn das Produkt jedoch vorhanden ist, möchten wir die vorhandenen Produktdaten mit den erhaltenen Daten aktualisieren (mehrere Attribute würden aktualisiert). Aufgrund der zu großen Datei Ich durchlaufe es mit XMLReader und übergebe die XML eines einzelnen Knotens, sobald ich einen Produktknoten erreicht habe. Dieser einzelne Knoten, der die Daten enthält, wird dann durch Simplexml geleitet, um die Verwendung zu vereinfachen.
Tropus

Antworten:

3

Der beste Anruf wäre getAllIds()meines Wissens.

Erläuterung

$collection = Mage::getModel('catalog/product')
                ->getCollection()
                ->addAttributeToSelect('sku')
                ->addAttributeToSelect("$supplier_name")
                ->addAttributeToSelect('production_nr')
                ->addAttributeToSelect('sku_supplier')
                ->addAttributeToFilter($supplier_name,array('eq' => $suppliers_product_nr));

Dies wird keine Zeit in Anspruch nehmen, da es sich lediglich um die Vorbereitung einer Sammlungsabfrage handelt. Diese Abfrage wird tatsächlich nur ausgeführt, wenn die Sammlung per load()Aufruf oder über foreach()Schleife oder über count()Aufruf usw. geladen wird .

Hier können Sie den Status der Sammlungsanzahl auf verschiedene Arten überprüfen. Ich liste sie in ihrer besten Leistungsbasis auf (die Leistung nimmt ab, während sie sinkt).

  • $collection->getAllIds() - Beste Option
  • $collection->getSize()
  • count($collection)
  • $collection->count() - Geringste Option

Warum diese Bestellung?

count()definiert in Varien_Data_Collectionund lädt zuerst die Sammlung und nimmt dann die Zählung durch Zählen der Sammlungselemente. Da die Sammlung geladen wird, dauert es am höchsten.

count($collection) habe keinen großen Unterschied zu oben.

getSize()definiert in Varien_Data_Collection_Dbund vermeidet das Laden von Sammlungen. Dies ist der große Vorteil hier. Dies gibt Ihnen eine gute Leistung, wenn Sie es zur Überprüfung verwenden. Siehe Antwort von Marius für weitere Details.

getAllIds()ist die beste Wahl. Diese Methode ist in verfügbar Mage_Eav_Model_Entity_Collection_Abstractund hat einen sehr subtilen Unterschied zur getSize()Definition, wodurch diese beste Wahl getroffen wird.

getAllIds()ruft intern auf getAllIdsSql()und sieht die Definition hier:

public function getAllIdsSql()
{
    $idsSelect = clone $this->getSelect();
    $idsSelect->reset(Zend_Db_Select::ORDER);
    $idsSelect->reset(Zend_Db_Select::LIMIT_COUNT);
    $idsSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
    $idsSelect->reset(Zend_Db_Select::COLUMNS);
    $idsSelect->reset(Zend_Db_Select::GROUP);
    $idsSelect->columns('e.'.$this->getEntity()->getIdFieldName());

    return $idsSelect;
}

Hier $idsSelect->columns('e.'.$this->getEntity()->getIdFieldName());ist, was diese Methode unter allen verfügbaren Methoden am besten macht. In der Tat fehlt diese Zeile in getSize().

Rajeev K Tomy
quelle
Ich habe -> getSize () für die Sammlung verwendet und fand sie etwas langsam (ca. 0,40 Sekunden pro Aufruf). Zunächst brauche ich nur ein Richtig oder Falsch, ob das Produkt existiert. Ist getAllIds () / getSize () wirklich der einzig schnellste Weg oder gibt es andere alternative Wege?
Tropus
Ich denke keine anderen alternativen Wege, um dies zu erreichen, um es zu überprüfen. Wenn Sie sich große Sorgen um die Ladezeit machen, können Sie Folgendes tun: 1. Sammlung so weit wie mager reduzieren 2. Sammlung mit Reichweite laden
Rajeev K Tomy
3

Der schnellste Weg für einen einzigen Anruf , ist die Verwendung getIdBySkuvon catalog/product:

if (Mage::getSingleton('catalog/product')->getIdBySku('yoursku')) {
  // Product exists
} else {
  // Product does not exist
}

Beachten Sie die getSingletonstatt getModelfür diese Verwendung!

Alternative:

Wenn Sie sie alle einmal einlesen müssen, können Sie sie getAllIds()aus einer Sammlung verwenden.

Phoenix128_RiccardoT
quelle
Wie würde ich den Anruf ändern, um die ID beispielsweise von etwas anderem als sku zu erhalten? (Bin ich richtig in der Annahme, dass es getIdByAttributeName ('attributevalue') sein würde)
Tropus
1

Wie unten von Rajeev K Tomy erwähnt, scheint die Geschwindigkeit der Abfrage mit der Methode getAllIds () in Magento am schnellsten zu sein. Sie können jedoch auch die erforderlichen Attributwerte (z. B. 'Production_nr' oder 'sku_supplier') abrufen, ohne die Sammlung zu laden. Diese Methode ist etwas langsamer als getAllIds ().

//addAttributeToSelect use only for EAV attributes
$collection = Mage::getModel('catalog/product')
    ->getCollection()
    ->addAttributeToSelect('meta_title', true) 
    ->addAttributeToSelect('meta_description', true)
    ->addAttributeToFilter(
        'name',
        array('like' => '%a%')
    );
//columns() use only for static attributes (product entity fields)
$collection->getSelect()->reset('columns')->columns(['entity_id', 'sku']);

/** @var Varien_Db_Select $select */
$select = $collection->getSelect();

/** @var Mage_Core_Model_Resource $res */
$res = Mage::getSingleton('core/resource');

/** @var Magento_Db_Adapter_Pdo_Mysql $conn */
$conn = $res->getConnection('core_write');
$res = $conn->fetchAll($select, Zend_Db::FETCH_ASSOC);

PS Fügen Sie der Sammlung nicht addAttributeToSelect ('name') hinzu, wenn Sie das Attribut 'name' für die Filtermethode verwenden.
PS2 Siehe meine Frage / Antwort über schnellste bekommen rohe Produktdaten ohne Lade Sammlung hier

sergei.sss
quelle