Performance dynamisches Tree-Menü

ronaldo84

Erfahrenes Mitglied
Hallo,

Folgende Situation wir haben Artikel die in bis zu 4 Produktgruppen unterteilt werden können. Dies kann, muss aber nicht sein. Dazu wollten wir ein Tree-Menü zur Navigation einsetzen. Dazu benutze ich folgendes Tree-Menü: Tutorial.
Um das ganze dynamische zu gestalten lese ich die Produktgruppen aus einer MySQL-Tabelle mittels PHP aus und generiere dann so den Code der für das Menü notwendig ist:
PHP:
$prodArr=connect("SELECT webshopPG1, count(*) as temp from webshop WHERE $kriterium webshopPG1 !='' GROUP by webshopPG1   ");
$countArr=connect("SELECT * from webshop");
echo "<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'><html><head><title>Produktgruppen</title>
<link rel='stylesheet' type='text/css' href='produktgruppe.css'>
<base target='produkt'></head>
<body bgcolor='#FFFFFF'><div id='menu' style='letter-spacing:0.001em; position:absolute; top:-5px;'>
<font face='verdana' color='##336699' size='2'><b>PRODUKTGRUPPE</b>:</font>
<ul>
<li><a href='produkt_shop.php4?PHPSESSID=$sid&amp;pg1=highlight&amp;pg2=&amp;pg3='><b>Preisaktionen</b> (".count($highArr).")</a></li>
<li><a href='produkt_shop.php4?PHPSESSID=$sid&amp;pg1=neuheit&amp;pg2=&amp;pg3='><b>Neuheiten</b> (".count($neuArr).")</a></li>";


for($i=0; $i<count($prodArr);$i++)
{    
    $tempprodukt=$prodArr[$i][webshopPG1];
    $anzahlprodukt=$prodArr[$i][temp];
    $tempArr2=connect("SELECT webshopPG2, count(*) as temp from webshop WHERE $kriterium webshopPG1='$tempprodukt' and webshopPG2 !='' GROUP BY webshopPG2  ");
    $temp=strtolower(preg_replace($badchar, $goodchar, $tempprodukt));
    if(count($tempArr2)>0)
    {
        echo "<li><a href='produkt_shop.php4?PHPSESSID=$sid&amp;pg1=$temp'><b>".strtoupper($tempprodukt)."</b>  (".$anzahlprodukt.")</a><ul>";
        for($y=0; $y<count($tempArr2); $y++)
        {
            $tempprodukt2=$tempArr2[$y][webshopPG2];
            $anzahl2=$tempArr2[$y][temp];
            $tempArr3=connect( "SELECT webshopPG3, count(*) as temp from webshop WHERE $kriterium webshopPG1='$tempprodukt' and webshopPG2='$tempprodukt2' and webshopPG3 !='' GROUP by webshopPG3  ");
            $temp2=strtolower(preg_replace($badchar, $goodchar, $tempprodukt2));
            if(count($tempArr3)>0)
            {    
                echo "<li><a href='produkt_shop.php4?PHPSESSID=$sid&amp;pg1=$temp&amp;pg2=$temp2' >".strtoupper($tempprodukt2)." (".$anzahl2.")</a><ul>";        

                for($z=0; $z <= count($tempArr3)-1;$z++)
                {         
                    
                    $tempprodukt3=$tempArr3[$z][webshopPG3];
                    $anzahl3=$tempArr3[$z][temp];
                    $tempArr4=connect("SELECT webshopPG4, count(*) as temp from webshop WHERE $kriterium webshopPG1='$tempprodukt' and webshopPG2='$tempprodukt2' and webshopPG3='$tempprodukt3' and webshopPG4!='' GROUP by webshopPG4 ");
                    $temp3=strtolower(preg_replace($badchar, $goodchar, $tempprodukt3));
                    if(count($tempArr4)>0)
                    {    
                        echo "<li><a href='produkt_shop.php4?PHPSESSID=$sid&amp;pg1=$temp&amp;pg2=$temp2&amp;pg3=$temp3'>".strtoupper($tempprodukt3)." (".$anzahl3.")</a><ul>";
                        for($x=0; $x<count($tempArr4); $x++)
                        {
                            $tempprodukt4=$tempArr4[$x][webshopPG4];
                            $anzahl4=$tempArr4[$x][temp];
                            $temp4=strtolower(preg_replace($badchar, $goodchar, $tempprodukt4));
                            echo "<li><a href='produkt_shop.php4?PHPSESSID=$sid&amp;pg1=$temp&amp;pg2=$temp2&amp;pg3=$temp3&amp;pg4=$temp4'>".strtoupper($tempprodukt4)." (".$anzahl4.")</a></li>";
                        }
                        echo "</ul>";
                        
                    }
                    else
                    {    echo "<li><a href='produkt_shop.php4?PHPSESSID=$sid&amp;pg1=$temp&amp;pg2=$temp2&amp;pg3=$temp3'>".strtoupper($tempprodukt3)." (".$anzahl3.")</a></li>";}
        
                }
                echo "</ul>";

            }
            else
            {

                    echo "<li><a href='produkt_shop.php4?PHPSESSID=$sid&amp;pg1=$temp&amp;pg2=$temp2'>".strtoupper($tempprodukt2)."  (".$anzahl2.")</a></li>";
            }
        }
        echo "</ul>";
    }
    else
    {
                echo "<li><a href='produkt_shop.php4?PHPSESSID=$sid&amp;pg1=$temp'><b>".strtoupper($tempprodukt)."</b>  (".$anzahlprodukt.")</a></li>";
    }
        
}
echo "</ul></div><script type='text/javascript' src='tree.js'>
</script></body></html>";
Das klappt auch soweit, dauert aber durch die zig Abfragen recht lange. Haba das dann alles auf Smarty-Templates umgestellt und es vresucht so zu beschleunigen:
PHP:
//PG holen
$pg1Arr=read("SELECT webshopPG1 FROM webshop GROUP BY webshopPG1");
$pg2Arr=read("SELECT webshopPG1, webshopPG2 FROM webshop GROUP BY webshopPG2");
$pg3Arr=read("SELECT webshopPG1, webshopPG2, webshopPG3 FROM webshop GROUP BY webshopPG3");
$pg4Arr=read("SELECT webshopPG1, webshopPG2, webshopPG3, webshopPG4 FROM webshop GROUP BY webshopPG4");
Im Template
HTML:
{foreach from=$pg1Arr item=pg1}
{assign var="adress" value=$pg1.webshopPG1|lower}
<li><a class="produktgruppe" href="index.php4?pg1={$adress}"><b>{$pg1.webshopPG1|upper|htmlentities|utf8_encode}</b> ({$pg1.anzahl})</a><ul>
{foreach from=$pg2Arr item=pg2}
{assign var="adress" value="pg1=`$pg1.webshopPG1`&amp;pg2=`$pg2.webshopPG2`"|lower}
{if $pg1.webshopPG1|lower==$pg2.webshopPG1|lower}
<li><a class="produktgruppe" href="index.php4?{$adress}"><b>{$pg2.webshopPG2|upper|htmlentities|utf8_encode}</b> ({$pg2.anzahl})</a>
{assign var="pg3_first" value="true"}
{assign var="pg3_last" value="false"}
{foreach from=$pg3Arr item=pg3}
{assign var="adress" value="pg1=`$pg1.webshopPG1`&amp;pg2=`$pg2.webshopPG2`&amp;g3=`$pg3.webshopPG3`"|lower}
{if $pg1.webshopPG1|lower==$pg3.webshopPG1|lower && $pg2.webshopPG2|lower==$pg3.webshopPG2|lower}
{if $pg3_first=="true"}<ul class="FirstPG3">{assign var="pg3_first" value="false"}{assign var="pg3_last" value="true"}{/if}
<li class="ANFPG3"><a class="produktgruppe" href="index.php4?{$adress}"><b>{$pg3.webshopPG3|upper|htmlentities|utf8_encode}</b> ({$pg3.anzahl})</a>
{assign var="pg4_first" value="true"}{assign var="pg4_last" value="false"}{foreach from=$pg4Arr item=pg4}
{assign var="adress" value="pg1=`$pg1.webshopPG1`&amp;pg2=`$pg2.webshopPG2`&amp;pg3=`$pg3.webshopPG3`&amp;pg4=`$pg4.webshopPG4`"|lower}
{if $pg1.webshopPG1|lower==$pg4.webshopPG1|lower && $pg2.webshopPG2|lower==$pg4.webshopPG2|lower && $pg3.webshopPG3|lower==$pg4.webshopPG3|lower}
{if $pg4_first=="true"}<ul class="first PG4">{assign var="pg4_first" value="false"}{assign var="pg4_last" value="true"}{/if}<li><a class="produktgruppe" href="index.php4?pg1={$adress}"><b>{$pg4.webshopPG4|upper|htmlentities|utf8_encode}</b> ({$pg4.anzahl})</a></li>{/if}{/foreach}{if $pg4_last=="true"}</ul class="LastPG4">{/if}</li class="EndePG3"> 
</li class="EndePG3">
{/if}
{/foreach}{if $pg3_last=="true"}</ul class="LastPG3">{/if}
{/if}
{/foreach}
</ul></li>
{/foreach}
Tut mir leid das der Smarty-Code nicht formatiert ist. Wenn ich das aber mache erhalte ich unnötige Absätze etc. in der generierten Datei. Das ist aber auch nicht sehr schneller, da er immer das komplette Array durchsucht. Hatte versucht einen Index auf die Produktgruppen zu legen, dadurch wurde es auch nicht sehr viel schneller. Hier mal die Tabellenstruktur:
SQL:
CREATE TABLE `t_webshop` (
  `artid` smallint(5) unsigned NOT NULL auto_increment,
  `artnr` mediumint(8) unsigned NOT NULL default '0',
  `Hersartnr` varchar(50) NOT NULL default '',
  `firma` varchar(50) NOT NULL default '',
  `name` varchar(100) NOT NULL default '',
  `beschreibung` mediumtext NOT NULL,
  `link` varchar(150) NOT NULL default '',
  `preis` decimal(9,2) unsigned NOT NULL default '0.00',
  `bildurl` varchar(100) NOT NULL default '',
  `bemerkungen` varchar(100) NOT NULL default '',
  `webshopPG1` varchar(40) NOT NULL default '',
  `webshopPG2` varchar(40) NOT NULL default '',
  `webshopPG3` varchar(40) NOT NULL default '',
  `webshopPG4` varchar(40) NOT NULL default '',
  PRIMARY KEY  (`artid`),
  KEY `pg` (`webshopPG1`(4),`webshopPG2`(4),`webshopPG3`(4),`webshopPG4`(4)),
  FULLTEXT KEY `firma, name` (`firma`,`name`),
  FULLTEXT KEY `firma, name, beschreibung` (`firma`,`name`,`beschreibung`)
Mir wäre da auch Nested set eingefallen, aber mein Chef will unbedingt die Tabellenstruktur beibehalten.
Ich bin nun langsam echt am verzweifeln. Hat jemand eine Idee wie ich das Beschleunigen könnte?

MFG

ronaldo

)
 
Zuletzt bearbeitet:
Das Forum sieht für jede Programmiersprache ihren eigenen "Tag" vor.
Zum Beispiel:
html = [code=html][/code]
html mit Highlight = [html4strict][/html4strict]
php = [code=php][/code]
sql = [code=sql][/code]
javascript = [code=javascript][/code]
css = [code=css][/code]
c = [c][/c]
Und noch zig andere. Das ist dann für andere besser lesbar.
 
Hi,

hatte auch zu tun das ich meine Kategoriebäume schneller aufbaue, geholfen hat da das Nested Set Modell
http://www.klempert.de/nested_sets/artikel/

Allerdings das alleine hatte meinen Ansprüchen nicht gereicht also habe ich das Model mit dem Rekursiven Aufruf kombiniert.

Würde dir also auch zu einer Kombination raten, in dem Link das dass alles eigentlich ganz gut erklärt, auch ne Performencegegenüberstellung zwischen einzelnen Modellen ist dabei.

Gruß
King of Darkness
 
Zurück