Neuigkeiten
  • Die modified eCommerce Shopsoftware ist kostenlos, aber nicht umsonst.
    Spenden
  • Damit wir die modified eCommerce Shopsoftware auch zukünftig kostenlos anbieten können:
    Spenden
  • Thema: ANLEITUNG: Viele Kategorien? Langsamer Shop? Hier box_categories Speedup!

    RossiRat

    • Fördermitglied
    • Beiträge: 96
    [...]
    ACHTUNG: Dieser Mod geht nur für Shops, welche die gunnART Categoriebox (Advanced Show Category 2.0 für xt:Commerce) eingebaut haben!

    Code: PHP  [Auswählen]
    /*
       GUNNART "SHOW_CATEGORY ADVANCED"

       erweiterte Kategorien-Navigation für xt:Commerce 3.04 SP1 / SP2.1

       Proudly togetherfummeled by Gunnar Tillmann
       http://www.gunnart.de
       Version 2.0 Beta 3 / April 2008
    */

     
    Wir haben 1200 Kategorien und das Erstellen der Kategorie-Box hat alleine 8-10 Sekunden gedauert. Laut Debugging wurden dabei rund 7000 Querries verursacht!  :doh:

    Ich habe mir ein eigenes Caching Modul für diverse Boxen geschrieben was die Abfragen umging. Aber nur solange niemand eine Kategorie ohne Cache aufrief, bzw. der Cache nicht abgelaufen war.  :(

    Also habe ich mir mal den Quellcode der Kategorie-Box angeschaut. Dort werden alle Kategorien abgefragt und dann abgearbeitet. Auch wenn man im Hauptverzeichnis ist und nur die (bei uns 10) Hauptkategorien abarbeiten müsste.  :datz:

    Daher habe ich den Code dahin gehend erweitert, das er nur die Hauptkategorien und alle Kategorien die im cPath angegeben sind ausliest und abarbeitet. Der Geschwindigkeitsvorteil bei vielen Kategorien ist enorm!  :B

    Bearbeitet werden muss die Datei "/source/boxes/categories.php" im aktuellen Template:

    Ersetze:

    Code: PHP  [Auswählen]
    $categories_query = "select c.categories_id,
                         cd.categories_name,
                         c.parent_id from "
    .TABLE_CATEGORIES." c, ".TABLE_CATEGORIES_DESCRIPTION." cd
                         where c.categories_status = '1'
                         and c.parent_id = '0'
                         "
    .$group_check."
                         and c.categories_id = cd.categories_id
                         and cd.language_id='"
    .(int) $_SESSION['languages_id']."'
                         order by sort_order, cd.categories_name"
    ;
    $categories_query = xtDBquery($categories_query);
     
    Durch:

    Code: PHP  [Auswählen]
    // Nur in beteiligten Kategorien suchen
    $cPath_array = array_filter(explode('_', trim($GLOBALS['cPath'])));
    $cPath_array[] = 0; // Root immer anzeigen
    $cat_filter_cPath = implode(', ', $cPath_array);

    $categories_query = "select c.categories_id,
                         cd.categories_name,
                         c.parent_id from "
    .TABLE_CATEGORIES." c, ".TABLE_CATEGORIES_DESCRIPTION." cd
                         where
                         c.parent_id in ("
    . $cat_filter_cPath . ")
                         and c.categories_status = '1'
                         "
    .$group_check."
                         and c.categories_id = cd.categories_id
                         and cd.language_id='"
    .(int) $_SESSION['languages_id']."'
                         order by sort_order, cd.categories_name"
    ;
    $categories_query = xtDBquery($categories_query);
     
    Es lohnt sich generell diese vielen überflüssigen Abfragen und die daraus resultierenden Unterabfragen (Anzahl der Artikel, ...) auszuschalten. Allerdings wird man mit wenigen Kategorien keinen großen Geschwindigkeitszuwachs erzielen.  :)

    [EDIT Tomcraft 16.05.2011: Fehler im Code korrigiert.]
    [EDIT Web28 17.05.2011: Dateiversion hinzugefügt.]



    Linkback: https://www.modified-shop.org/forum/index.php?topic=12890.0

    GTB

    • modified Team
    • Gravatar
    • Beiträge: 6.306
    • Geschlecht:
    und wenn jetzt auch noch die SQL Abfragen gecached werden ...

    Danke fürs teilen.

    Gruss Gerhard

    0815

    • Viel Schreiber
    • Beiträge: 905
    Hallo,

    im Testshop habe ich das eben mal ausprobiert.
    In einer Hauptkategorei werden weitere Unterkategorien angezeigt.
    In den Unterkategorien werden allerdings leider die Unterkategorien der nächsten Ebene nicht angezeigt, sondern immer die Hauptkategorien.

    Zum Test habe ich mal folgendes auskommentiert:
    Code: PHP  [Auswählen]
    $cPath_array[] = 0; // Root immer anzeigen
    So funktioniert es dann zwar auch mit den Unter-unterkategorien, allerdings wird in der Kategoriebox gar nichts mehr angezeigt und es kommt auch auf der Statzseite zu einem SQL-Fehler.

    Wurde die Anpassung bereits auf Funktion getestet, wenn ein Shop Kategorien auf mehr als 2 Ebenen hat?

    mathias75

    • Neu im Forum
    • Beiträge: 8
    Hi,

    hab den Codeblock eben mal bei uns ausgetauscht, leider besteht das genannte Problem auch hier.

    Bin in einer Stunde wieder bei mir in der Wohnung, dann schaue ich mir das nochmal genauer an. Ist sicherlich eine super Änderung, da wir doch so einige Artikel und Kategorien haben.

    Gruß Mathias

    RossiRat

    • Fördermitglied
    • Beiträge: 96
    Den Code habe ich bei uns im neuen Shop im Einsatz: Unser neuer Shop für Motorradteile

    Dort geht es bis zum 4-stufigen Kategoriebaum: Startseite » Moto Guzzi » Auspuffanlage » Endschalldämpfer » Agostini

    Mein Code benutzt die interne Kategoriebaumangabe cPath - Habt Ihr vielleicht irgendwelche Mods laufen die daran was ändern? bei uns ist da alles von der Stange, inkl. Shopstat.

    EDIT: Habe glaube ich den Fehler gefunden. Verbesserte Version:

    Code: PHP  [Auswählen]
    // Nur in beteiligten Kategorien suchen
    $cPath_array = array_filter(explode('_', trim($GLOBALS['cPath'])));
    $cPath_array[] = 0; // Root immer anzeigen
    $cat_filter_cPath = implode(', ', $cPath_array);
     
    $categories_query = "select c.categories_id,
                         cd.categories_name,
                         c.parent_id from "
    .TABLE_CATEGORIES." c, ".TABLE_CATEGORIES_DESCRIPTION." cd
                         where
                         c.parent_id in ("
    . $cat_filter_cPath . ")
                         and c.categories_status = '1'
                         "
    .$group_check."
                         and c.categories_id = cd.categories_id
                         and cd.language_id='"
    .(int) $_SESSION['languages_id']."'
                         order by sort_order, cd.categories_name"
    ;
    $categories_query = xtDBquery($categories_query);
     
    Das doppelte Abfragen der "parent_id" muss raus ("and c.parent_id = '0'"). War mein Fehler beim Einstellen. Hatte extra eine frische Datei aus dem aktuellen Archiv genommen und erweitert. Bitte nochmal testen!

    mathias75

    • Neu im Forum
    • Beiträge: 8
    Hi,

    hab den geänderten Code eingespielt, jetzt kommt bei den meisten Kategorien eine weiße Seite und auch Artikel bleiben weiß.

    Schau mir jetzt mal meine Änderungen im System an, wodran dies liegen kann. Am Shop ist über die Jahre "leider" so einiges angepasst...

    categories.php ist soweit ich das sehen kann unverändert und modified eCommerce Shopsoftware, shopstat ist auch aktiv.

    ich probiere mal ein paar Sachen aus.

    Gruß Mathias

    web28

    • modified Team
    • Beiträge: 9.404
    Code: PHP  [Auswählen]
    $categories_query = "select c.categories_id,
                         cd.categories_name,
                         c.parent_id from "
    .TABLE_CATEGORIES." c, ".TABLE_CATEGORIES_DESCRIPTION." cd
                         where c.categories_status = '1'
                         and c.parent_id = '0'
                         "
    .$group_check."
                         and c.categories_id = cd.categories_id
                         and cd.language_id='"
    .(int) $_SESSION['languages_id']."'
                         order by sort_order, cd.categories_name"
    ;
    $categories_query = xtDBquery($categories_query);
     
    Also diese Abfrage mit der oben genannten zu ersetzen bringt gar nichts. Im Gegenteil, durch das unnötige Array wird die Abfrage langsamer.
    An dieser Stelle werden ja nur die Hauptkategorien abgefragt (c.parent_id = '0')

    Die Abfrage für den Kategoriebaum ist ja weiter unten im Code in der "while" Schleife.

    Poste mal Deine "categories.php" als ZIP.

    Gruss Web28

    mathias75

    • Neu im Forum
    • Beiträge: 8
    anbei die aktuelle categories.php

    hatte vorhin noch eine ältere Fassung. Jetzt diese mit dem gleichen Ergebnis, Unter-Unterkategorien werden nicht dargestellt, sondern dann dafür die Hauptkategorien.

    Gruß Mathias

    RossiRat

    • Fördermitglied
    • Beiträge: 96
    @Mathias
    In Zeile 61 hast Du noch den alten, defekten Code drin. Ich hatte ja schon die fehlerbereinigte Version gepostet.

    Deine Zeile:

    Code: PHP  [Auswählen]
    $categories_query = "select c.categories_id,
                         cd.categories_name,
                         c.parent_id from "
    .TABLE_CATEGORIES." c, ".TABLE_CATEGORIES_DESCRIPTION." cd
                         where
                         c.parent_id in ("
    . $cat_filter_cPath . ")
                         and c.categories_status = '1'
                         and c.parent_id = '0'
                         "
    .$group_check."
                         and c.categories_id = cd.categories_id
                         and cd.language_id='"
    .(int) $_SESSION['languages_id']."'
                         order by sort_order, cd.categories_name"
    ;
    $categories_query = xtDBquery($categories_query);
    Die richtige Version:

    Code: PHP  [Auswählen]
    $categories_query = "select c.categories_id,
                         cd.categories_name,
                         c.parent_id from "
    .TABLE_CATEGORIES." c, ".TABLE_CATEGORIES_DESCRIPTION." cd
                         where
                         c.parent_id in ("
    . $cat_filter_cPath . ")
                         and c.categories_status = '1'
                         "
    .$group_check."
                         and c.categories_id = cd.categories_id
                         and cd.language_id='"
    .(int) $_SESSION['languages_id']."'
                         order by sort_order, cd.categories_name"
    ;
    $categories_query = xtDBquery($categories_query);
    Ich würde gerne meinen ersten Beitrag ändern, damit nicht noch mehr den ersten Entwurf mit dem Fehler einbauen. Wie kann ich denn den Beitrag ändern um die Zeile "and c.parent_id = '0'" zu entfernen?

    web28

    • modified Team
    • Beiträge: 9.404
    @RossiRat

    Poste bitte auch Deine "categories.php" als ZIP.

    Gruss Web28

    DokuMan

    • modified Team
    • Beiträge: 6.669
    • Geschlecht:
    Wir haben da auch mal was geändert.

    @web28: was ist damit (/trunk/templates/source/boxes/categories.php aus r1467)?

    Code: PHP  [Auswählen]
    and cd.language_id='".$_SESSION['languages_id']."'
    and trim(cd.categories_name) != ''                      //<--
    order by sort_order, cd.categories_name";

    RossiRat

    • Fördermitglied
    • Beiträge: 96
    [...]
    An dieser Stelle werden ja nur die Hauptkategorien abgefragt (c.parent_id = '0')
    [...]

    Hallo Web28,
    2 Postings drüber hatte ich ja den Fehler schon bereinigt. Hast Du mal die aktuellste Version ausprobiert?

    [...]
    Die Abfrage für den Kategoriebaum ist ja weiter unten im Code in der while Schleife.
    [...]

    Das stimmt. Aber dort werden nur die Ergebnisse abgearbeitet, welche von dieser Abfrage hier gefunden werden. Und wenn statt 1000 Kategorien nur ca. 30 ausgelesen werden, dann spart das enorm viel Serverlast & Ladezeit.

    EDIT: Meine "categoties.php" ist im Anhang. Die ist aber überarbeitet. Deswegen hatte ich meine Erweiterung extra in eine neue, saubere Quelldatei eingebaut (Und dabei den "parent_id = 0" übersehen).

    luckybaron

    • Mitglied
    • Beiträge: 168
    Ich kann mich jetzt auch irren, aber hat gunnART da nicht schon mal was an der Performance der Kategorien geschraubt? In meiner "/template/xtc5/source/boxes/categories.php" sieht es so aus:

    Code: PHP  [Auswählen]
    [...]
            $box_smarty = new smarty;

            if(!CacheCheck() && !FORCE_CACHE) {
                    $cache=false;
                    $box_smarty->caching = 0;
            } else {
                    $cache=true;
                    $box_smarty->caching = 1;
                    $box_smarty->cache_lifetime = CACHE_LIFETIME;
                    $box_smarty->cache_modified_check = CACHE_CHECK;
                    $cache_id = $_SESSION['language'].$_SESSION['customers_status']['customers_status_id'].$cPath;
            }
    if(!$box_smarty->is_cached(CURRENT_TEMPLATE.'/boxes/box_categories.html',$cache_id) || !$cache) {

                    require_once (DIR_FS_CATALOG.'templates/'.CURRENT_TEMPLATE.'/source/inc/gunnart_Categories.inc.php');
                    $CatConfig = array(
                            'MinLevel'              =>      2,
                            'MaxLevel'              =>      6,
                            'HideEmpty'             =>      false,
                            'ShowCounts'    =>      false,
                            'CatNaviID'             =>      'categorymenu'
                    );
                    $box_smarty->assign('language',$_SESSION['language']);
                    $box_smarty->assign('tpl_path','templates/'.CURRENT_TEMPLATE.'/');
                    $box_smarty->assign('BOX_CONTENT',gunnartCategories(0,1,$CatConfig));

            }

            if(!$cache) {
                    $box_categories = $box_smarty->fetch(CURRENT_TEMPLATE.'/boxes/box_categories.html');
            } else {
                    $box_categories = $box_smarty->fetch(CURRENT_TEMPLATE.'/boxes/box_categories.html',$cache_id);
            }
            $smarty->assign('box_CATEGORIES',$box_categories);
    Ich habe für meine Kategorien dieses Modul verwendet: MODUL: Aktive Kategorie hervorheben
    Gut ich habe auch keine 1200 Kategorien in meinem Testshop, deshalb kann ich nichts zur Performance sagen. Habe das Modul damals nur verbaut da man damit leere Kategorien verstecken kann.

    web28

    • modified Team
    • Beiträge: 9.404
    Die Queryabfragen habe ich nur mit

    Code: PHP  [Auswählen]
    and trim(cd.categories_name) != ''
    Das ist wichtig für Mehrsprachshops, bei denen die Kategorien nicht in jeder Sprache angelegt sind.

    An den eigentlichen Abfragen lässt sich meiner Meinung außer mit INNER JOIN nichts wesentlich optimieren.

    Die Änderung von RossiRat bringt leider gar nichts.

    RossiRat

    • Fördermitglied
    • Beiträge: 96
    [...]
    Die Änderung von RossiRat bringt leider gar nichts.

    Hast Du das mein Code wirklich ausprobiert und die Anzahl der ausgeführten Queries überprüft? Bei mir ging die Anzahl der Queries pro Seite von knapp über 7000 auf 500 runter. Und zwar reproduzierbar.

    Ich befasse mich nicht mit der Bezeichnung der Kategorien. Daher ist für meine Änderung auch ein geänderter JOIN nicht von Belang. Mein Code unterdrückt direkt überflüssige Abfragen in der Kategoriebox. Dort müssen nur noch die Hauptkategorien und die gerade aktiven Kategorien abgearbeitet werden. Der Rest an Abfragen ist überflüssiger Ballast.

    Nebenbei: Wie kann ich denn meinen ersten Post bearbeiten, so das dort nicht mehr der fehlerhafte Code auftaucht? Oder sind Postings ab x Tagen automatisch gesperrt?

    10 Antworten
    2824 Aufrufe
    21. Oktober 2019, 23:22:48 von hpzeller
    1 Antworten
    164 Aufrufe
    10. Juli 2024, 09:36:08 von Markus
    1 Antworten
    2953 Aufrufe
    18. Dezember 2014, 15:56:15 von Godzilla
    4 Antworten
    13397 Aufrufe
    26. Januar 2017, 12:18:26 von Jonas