Magento-Indizes manuell neu erstellen

Ab und zu müssen Magento-Indizes aufgeräumt werden. (c) Horrgakx auf flickr.comDer Kommentar von vansiegmund hat mich dazu ermuntert, einen alten Posting-Entwurf hervorzukramen, und zwar die Antwort auf die Frage: wie kann ich mit PHP-Code einen Index neu aufbauen? Genauer gesagt wollte vansiegmund wissen, wie er mit einem PHP-Skript eine Re-Indizierung nach dem SOAP-Import veranlasst.

Ich nehme Magento 1.4.2.0 als Basis. In der neuen Version 1.5.0.1 habe ich noch nicht nachgesehen, aber vermutlich ist der Ablauf dort ähnlich.

Neu-Indizierung per Shell-Skript

Wenn ihr die Indizes über ein Bash-Skript aktualisieren wollt, könnt ihr auf die Datei shell/indexer.php zurückgreifen.

Der Aufruf ohne Parameter liefert Informationen zur Verwendung des Skripts:

Wenn wir alle Indizes neu aufbauen wollen, reicht uns somit folgender Befehl:

Oft ist das aber gar nicht nötig, da von Updates nur einzelne Indizes betroffen sind.
Sehen wir uns an, welche Indizes zur Verfügung stehen:

Wir können uns nun näher informieren, ob der Index automatisch oder manuell aktualisiert wird und ob eine Neuberechnung gerade nötig ist:

Weitere Index-Status sind

  • Require Index (muss neu indiziert werden),
  • Running (Indizierung läuft momentan) und
  • Ready (Index ist aktuell).

Entschließen wir uns nun dazu, einen Index zu erneuern, dann sieht das so aus:

Diese Meldung erscheint für jeden einzelnen Index. Falls die Indizierung misslingt, wird eine entsprechende Fehlermeldung oder – falls keine vorhanden ist – die Meldung

ausgeworfen.

Indizierungsmodus ändern

In manchen Situationen ist es sinnvoll, die automatische Indizierung vorübergehend zu deaktivieren. Zum Beispiel haben meine Tests zur Performance des SOAP-Imports ergeben, dass die Umstellung auf manuelle Indizierung ein Viertel der Zeit einspart.

In der Shell kann man dank indexer.php den Modus für einzelne oder alle Indizes ändern:

Neu-Indizierung per PHP-Skript

Um einen Index per PHP zu aktualisieren, benötigt man nichts weiter als die Datei app/Mage.php.

Mit dem folgenden Befehl werden der Index sowie alle von ihm abhängigen Indizes neu geschrieben. Alternativ kann man reindexAll() verwenden. Dann werden Abhängigkeiten nicht berücksichtigt.

Wenn alle Indizes auf Vordermann gebracht werden sollen, holt man sich eine Prozess-Collection und ruft für jede einzelne reindexAll() auf. reindexEverything kann man sich in diesem Fall ersparen, da ohnehin jeder Index an die Reihe kommt.

Indizierungsmodus ändern

Natürlich kann man auch im PHP-Skript den Modus ändern, um beim Import Zeit zu sparen. Für den folgenden Code ergeht ein Dankeschön an Ivan Chepurnyi bei Stackflow:

Fazit

Nun steht hoffentlich nichts mehr im Weg, um Magentos Indizes auf dem aktuellen Stand zu halten!

Das könnte Ihnen auch gefallen...

19 Antworten

  1. vansiegmund sagt:

    Hallo Matthias,

    ich habe mein Script nun komplett umgebaut und den Test auf der Shopversion 1.5.0.1 durchgefürt:

    real 9m29.408s
    user 6m9.103s
    sys 0m57.852s

    für 2650 Produkte, das ist doch super 10-12 Produkte pro Sekunde 😉

    „walk(’setMode‘, array(Mage_Index_Model_Process::MODE_MANUAL));“

    haben in meinem Script noch gefehlt.

    Grüße

    Fetten Dank auch an meiner Stelle an Ivan Chepurnyi von Stackflow!

    • Hallo,

      das ist wirklich eine schöne Performance-Steigerung! 😉
      Darf ich fragen, was du bei dem Test alles durchführst? (Kategorie-Zuordnungen, Bilder, Sprachen…)

      lg Matthias

      • vansiegmund sagt:

        Guten Morgen,

        derzeit erstelle ich nur die Produkte, bzw. überspiele die bestehenden um einen schnellen Stock und Price Update zu erzielen.

        Um die ganze Sache komplett rund zu bekommen fehlt mir noch die On The Fly Produktgruppenerstellung, beim Artikelimport.
        Leider komme ich nicht hinter wie die Magento Api zur Produktgruppenanlage intern aufgebaut ist. Habe schon das Netz durchforstet aber nur den Standard zur Produktanlage gefunden…

        http://www.fontis.com.au/blog/magento/creating-magento-products-script

        Hast du einen Tipp für mich? Das ist der Ansatz aus meinem Standard API Import.

        if(!array_key_exists($s1, $c1)) {

        $id_level1 = $category->setData(2, array(’name’=>$s1,
        ‚is_active’=>1,
        ‚include_in_menu’=>1,
        ‚available_sort_by’=>array(0),
        ‚default_sort_by’=>’Bewertung‘)
        );
        $c1[$s1] = $id_level1;

  2. Matthias sagt:

    Hi Matthias, 🙂

    ist es ratsam ein Reindex in ein Setup-Script einzubauen? Oder spricht etwas dagegen (lange Laufzeiten z.B.)?

    Grüße

    Matthias

    • Hi Matthias ;),
      in einem Live-System sehe ich die Gefahr, dass durch die längere Laufzeit mehrere Besucher das Upgrade-Script auslösen. Wenn die Site für alle anderen gesperrt wird, solange die Aktualisierung läuft, sollte es kein Problem sein. Am besten einfach einmal die Auswirkung in einem Staging-System testen.
      Als Alternativen bleiben immer noch ein Cronjob, Shell-Script oder das Backend für die Neu-Indizierung.

  3. Giorgio sagt:

    Ich habe auch ein Problme mit dem Index in Magento der ständig auf Verarbeitung stecken bleibt. Ich wollte diesen php Befehl probieren habe auch einen SSH Zugang zu Servplatz allerdings habe ich keine Ahnung wie ich den Befehl: php indexer.php –reindex absetzen soll?
    Über FTP?
    Welches Programm brauche ich da, ist der Symtax für den Befehl ok?
    Kann ich auch ein Script auf dem Server in den Ordner Magento Ordenr shell ablegen, dass ich dann mit einem Browser aufrufe?
    Sorry bin da etwas unbeholfen, da ich sowas noch nicht gemacht habe.
    Ich finde zwar jede Menge Hinweise hierzu aber keine Hinweise wie man da GENAU vorgeht:

    Danke für jede Hilfe

  4. JCG sagt:

    Das ist alles perfekt beschrieben und sehr hilfreich, daher habe ich auch nur eine Kleinigkeit anzumerken:

    Der Plural von „Status“ ist nicht „Stati“, sondern aufgrund der u-Deklination „Status“. 🙂

    Viele Grüße,
    Jan

    • Hallo Jan,

      danke für den Hinweis – ist ausgebessert.

    • Thorsten sagt:

      Danke für den Post. Schöne Zusammenfassung 🙂

      Aktuell bauen sich die Indizes bei uns leider überhaupt nicht mehr auf.

      Next exception ‚Zend_Db_Statement_Exception‘ with message ‚SQLSTATE[42000]: Syntax error or access violation: 1118 Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
      CREATE TABLE catalog_product_flat_14 (

      Ebenso dauert das Attribute und Produkte speichern leider ewig.
      Gibt es Shops, die die Indizies komplett auf manuell stellen und nur nachts per Cron aktualisieren?

      Gruß Thorsten

      • Danke für das Lob! In dem Shop ist bei zu vielen Attributen die Einstellung „Used in Product Listing“ auf „Yes“ gesetzt. Dadurch stoßt ihr bei den Flat-Tables an eine Grenze von MySQL. Überprüft einmal, ob die Einstellung wirklich bei so vielen Attributen benötigt wird.

        Ja, es gibt Shops, die das machen!

  5. Robert Piper sagt:

    Hi Matthias,

    vielen Dank für deinen Blog 🙂

    wenn ich über die shell catalog_product_price reindexen will bekomme ich folgende Fehlermeldung:

    /html/mage-672c1fbd/shell$ php indexer.php –reindex catalog_product_price
    Product Prices index process unknown error:
    exception ‚PDOException‘ with message ‚SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count
    doesn’t match value count at row 1‘ in /html/mage-672c1fbd/lib/Zend/Db/Statement/Pdo.php:228
    Stack trace:
    #0 /html/mage-672c1fbd/lib/Zend/Db/Statement/Pdo.php(228): PDOStatement->execute(Array)
    #1 /html/mage-672c1fbd/lib/Varien/Db/Statement/Pdo/Mysql.php(110): Zend_Db_Statement_Pdo->_execute(Array)
    #2 /html/mage-672c1fbd/app/code/core/Zend/Db/Statement.php(291): Varien_Db_Statement_Pdo_Mysql->_execute(Array)
    #3 /html/mage-672c1fbd/lib/Zend/Db/Adapter/Abstract.php(479): Zend_Db_Statement->execute(Array)
    #4 /html/mage-672c1fbd/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query(‚INSERT INTO ca...',
    Array)
    #5 /html/mage-672c1fbd/lib/Varien/Db/Adapter/Pdo/Mysql.php(428): Zend_Db_Adapter_Pdo_Abstract->query('INSERT INTO
    ca..
    .‘, Array)
    #6 /html/mage-672c1fbd/app/code/community/OrganicInternet/SimpleConfigurableProducts/Catalog/Model/Resource/Eav/Mysql4/
    Product/Indexer/Price/Configurable.php(133): Varien_Db_Adapter_Pdo_Mysql->query(‚INSERT INTO ca...')
    #7 /html/mage-672c1fbd/app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Price/Configurable.php(48): OrganicInt
    ernet_SimpleConfigurableProducts_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price_Configurable->_prepareFinalPri
    ceData()
    #8 /html/mage-672c1fbd/app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Price.php(385): Mage_Catalog_Model_Res
    ource_Product_Indexer_Price_Configurable->reindexAll()
    #9 /html/mage-672c1fbd/app/code/core/Mage/Index/Model/Indexer/Abstract.php(143): Mage_Catalog_Model_Resource_Product_In
    dexer_Price->reindexAll()
    #10 /html/mage-672c1fbd/app/code/core/Mage/Index/Model/Process.php(210): Mage_Index_Model_Indexer_Abstract->reindexAll(
    )
    #11 /html/mage-672c1fbd/app/code/core/Mage/Index/Model/Process.php(258): Mage_Index_Model_Process->reindexAll()
    #12 /html/mage-672c1fbd/shell/indexer.php(166): Mage_Index_Model_Process->reindexEverything()
    #13 /html/mage-672c1fbd/shell/indexer.php(212): Mage_Shell_Compiler->run()
    #14 {main}

    Next exception 'Zend_Db_Statement_Exception' with message 'SQLSTATE[21S01]: Insert value list does not match column lis
    t: 1136 Column count doesn't match value count at row 1' in /html/mage-672c1fbd/lib/Zend/Db/Statement/Pdo.php:234
    Stack trace:
    #0 /html/mage-672c1fbd/lib/Varien/Db/Statement/Pdo/Mysql.php(110): Zend_Db_Statement_Pdo->_execute(Array)
    #1 /html/mage-672c1fbd/app/code/core/Zend/Db/Statement.php(291): Varien_Db_Statement_Pdo_Mysql->_execute(Array)
    #2 /html/mage-672c1fbd/lib/Zend/Db/Adapter/Abstract.php(479): Zend_Db_Statement->execute(Array)
    #3 /html/mage-672c1fbd/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query('INSERT INTO
    ca…‘,
    Array)
    #4 /html/mage-672c1fbd/lib/Varien/Db/Adapter/Pdo/Mysql.php(428): Zend_Db_Adapter_Pdo_Abstract->query(‚INSERT INTO ca..
    .', Array)
    #5 /html/mage-672c1fbd/app/code/community/OrganicInternet/SimpleConfigurableProducts/Catalog/Model/Resource/Eav/Mysql4/
    Product/Indexer/Price/Configurable.php(133): Varien_Db_Adapter_Pdo_Mysql->query('INSERT INTO
    ca…‘)
    #6 /html/mage-672c1fbd/app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Price/Configurable.php(48): OrganicInt
    ernet_SimpleConfigurableProducts_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price_Configurable->_prepareFinalPri
    ceData()
    #7 /html/mage-672c1fbd/app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Price.php(385): Mage_Catalog_Model_Res
    ource_Product_Indexer_Price_Configurable->reindexAll()
    #8 /html/mage-672c1fbd/app/code/core/Mage/Index/Model/Indexer/Abstract.php(143): Mage_Catalog_Model_Resource_Product_In
    dexer_Price->reindexAll()
    #9 /html/mage-672c1fbd/app/code/core/Mage/Index/Model/Process.php(210): Mage_Index_Model_Indexer_Abstract->reindexAll()

    #10 /html/mage-672c1fbd/app/code/core/Mage/Index/Model/Process.php(258): Mage_Index_Model_Process->reindexAll()
    #11 /html/mage-672c1fbd/shell/indexer.php(166): Mage_Index_Model_Process->reindexEverything()
    #12 /html/mage-672c1fbd/shell/indexer.php(212): Mage_Shell_Compiler->run()
    #13 {main}

    Hast evtl. einen Ansatz wie ich das beheben kann, da ich keine neuen Konfigurierbaren Artikel mehr in Kategorien verlinken kann?

    Vielen lieben Dank!

    • Hallo, der Fehlermeldung nach mischt die Extension OrganicInternet_SimpleConfigurableProducts bei dem Code-Teil mit. Die Extension kenne ich nicht. Frage bei dem Hersteller nach, der wird am besten helfen können.

      • Robert Piper sagt:

        Hallo, vielen Dank für deine schnelle Antwort. Ich hab die Extension neu installiert und jetzt funktioniert wieder alles 🙂 Danke

  6. Florian sagt:

    Hey Matthias,

    danke für den Beitrag.

    Ich habe momentan in einem Shop (1.7) ein Phänomen, welches ich mir nicht erklären kann. Vielleicht hast du mir einen Quick-Tipp?

    Ich indexiere – je nach Bedarf – über einen nächtlichen Cronjob, welcher die Indexe direkt aktuallisiert oder auch über die Shell. Jeweils wird immer nur ein einzelner Index aktuallisiert. (Also nicht über reindexall).
    Ab und an wurde z.B. das Fertigstellungs-Datum des Attribut-Index nicht mehr aktuallisiert und auch das Backend-Feld „Update erforderlich“ blieb immer auf rot. (lt. Shell-Ausgabe keinerlei Fehler).
    Nach dem leeren der index_event und index_process_event Tabellen lief es dann wieder tadellos. Für ein paar Tage.
    Nun bringt jedoch selbst das leeren dieser Tabellen nichts mehr. Der Index wird zwar geupdated, jedoch nicht das Datum sowie der Flag „Update erforderlich“. Auch der Status wechselt direkt nach dem Ausführen von „Verarbeiten“ wieder zu „Neuaufbau nötig“. Somit startet der nächtliche Index-Update immer wieder beim Attribut-Index und führt die restlichen nicht aus.
    Zur Info: Alle Indexes (bis auf Lagerbestand), stehen auf „Manuelles Update“. All diese Indexe betrifft das selbe Problem.

    Ich hoffe, du kannst mir hier weiterhelfen!

    Liebe Grüße aus Kempten und schonmal ein „Danksche“.

    • Ich würde als Erstes sicherstellen dass der PHP-Prozess ein ausreichend hohes Memory-Limit hat – wohlgemerkt auch in der PHP-Konfiguration für die Shell. Dann würde ich die diversen Magento-Logs und den PHP-Error-Log beobachten. Normalerweise spucken fehlerhafte Indizierungsprozesse eine Meldung aus.

  1. 24.02.2011

    […] This post was mentioned on Twitter by Matthias Zeis and LimeSoda, Bernd Pfeiffer. Bernd Pfeiffer said: RT @mzeis: How to update #magento indexes programmatically using PHP or shell http://ow.ly/42nIN (in German) […]

  2. 07.03.2011

    […] Zeis, bekannt durch seine guten umfangreichen Beiträge, hat sich einmal näher mit dem Indexer-Prozess beschäftigt. Ganz gut erklärt und noch mal ein wenig umfangreicher als unser eigener Beitrag zu […]