Model->load($id) vs. Model->getCollection()->getItemById($id)

Veröffentlicht am 20.08.2010 von jkuensebeck in der Schublade Magento | Tags: , , | Ein Kommentar »

Neulich bin ich in einer älteren Version einer in Deutschland sehr beliebten Extension über einen lustigen kleinen Performance-Killer gestolpert: Es sollte ein Quote-Object anhand der ID geladen werden, das sah im Code folgendermaßen aus:

$quote = Mage::getModel('sales/quote')->getCollection()->getItemById($quote_id);

harmlos, oder? Nein!

Diese eine Zeile brauchte ca. 30 Sekunden, und das auf einem wirklich performanten Kundenserver.
Wie kommt’s?

In lib/Varien/Data/Collection.php finden wir folgendes:

    /**
     * Retrieve item by id
     *
     * @param   mixed $idValue
     * @return  Varien_Object
     */
    public function getItemById($idValue)
    {
        $this->load();
        if (isset($this->_items[$idValue])) {
            return $this->_items[$idValue];
        }
        return null;
    }

Zuerst wird die gesamte Collection geladen, und dann per Array-Lookup das richtige Element zurückgegeben. Die gesamte Collection laden bedeutete in diesem Fall 50.000 Quotes aus der Datenbank abholen, 50.000 mal den Konstruktor der Klasse aufrufen, und dann den EINEN verdammten Eintrag zurückgeben.
Wir haben diese Zeile dann durch das gute alte Mage::getModel(‘sales/quote’)->load($id) ersetzt und konnten so die Performance um den Faktor 50.000 erhöhen;)
Ich frage mich was die Idee hinter dieser Methode ist und warum eine dermaßen nicht skalierende Methode überhaupt im Magento-Core vorhanden ist. Oder gibt es da vernünftige Einsatzbereiche?


Ein Kommentar zu “Model->load($id) vs. Model->getCollection()->getItemById($id)”

  1. 1 Torsten W sprach am 23.07.2011 um 11:15:

    Hi,

    ja das macht sinn. Wenn man mit einer gefilterten Collection arbeitet und nur aus dieser einen bestimmten Datensatz haben will.

    Der 2. Vorteil bei gut gefilterten Collections ist auch, dass man explizit steuern kann, welche Attribute der EAV geladen werden sollen und welche nicht.