Avatar billede buxxy Praktikant
10. januar 2012 - 11:19 Der er 7 kommentarer og
1 løsning

Optimering af SQL-forespørgsler

Hej Eksperter.

Jeg har flg. kode til en dropdown menu. Dog synes jeg der bruges for mange forespørgsler - som stiger i takt med oprettede menupunkter:

//  ============================== Main Menu Start ============================== //
$msql = dbquery("SELECT * FROM ".DB_MENUS." WHERE menu_cat='0' ORDER BY menu_order");
if (dbrows($msql) != 0) {
  echo "<ul id='nav'>";
  while ($mdata = dbarray($msql)) {
    if (checkgroup($mdata['menu_access'])) {     
      $link_target = ($mdata['menu_window'] == "1" ? " target='_blank'" : "");
        if(dbrows(dbquery("SELECT menu_cat FROM ".DB_MENUS." WHERE menu_cat='".$mdata['menu_id']."'"))) {
          $div_class = " class='down'";
          } else {
            $div_class = "";
          }
            if ($mdata['menu_name'] !== "---" && $mdata['menu_link'] == "---") {
              if (preg_match("!^(ht|f)tp(s)?://!i", $mdata['menu_link'])) {
                echo "<li class='top'><div".$div_class."><a href='".$mdata['menu_link']."'".$link_target." class='top_link'>".parseubb($mdata['menu_name'], "b|i|u|img|color")."</a></div>\n";
              } else {
                echo "<li class='top'><div".$div_class."><a href='".BASEDIR.$mdata['menu_link']."'".$link_target." class='top_link'>".parseubb($mdata['menu_name'], "b|i|u|img|color")."</a></div>\n";
              }
            } else if ($mdata['menu_name'] !== "---" && $mdata['menu_link'] == "") {
              if (preg_match("!^(ht|f)tp(s)?://!i", $mdata['menu_link'])) {
                echo "<li class='top'><div".$div_class."><a href='".$mdata['menu_link']."'".$link_target." class='top_link'>".parseubb($mdata['menu_name'], "b|i|u|img|color")."</a></div>\n";
              } else {
                echo "<li class='top'><div".$div_class."><a href='".BASEDIR.$mdata['menu_link']."'".$link_target." class='top_link'>".parseubb($mdata['menu_name'], "b|i|u|img|color")."</a></div>\n";
              }
            } else if ($mdata['menu_name'] == "---" && $mdata['menu_link'] == "---") {
              echo "<li class='top'><hr />\n";
            } else {
              if (preg_match("!^(ht|f)tp(s)?://!i", $mdata['menu_link'])) {
                echo "<li class='top'><div".$div_class."><a href='".$mdata['menu_link']."'".$link_target." class='top_link'>".parseubb($mdata['menu_name'], "b|i|u|img|color")."</a></div>\n";
              } else {
              echo "<li class='top'><div".$div_class."><a href='".BASEDIR.$mdata['menu_link']."'".$link_target." class='top_link'>".parseubb($mdata['menu_name'], "b|i|u|img|color")."</a></div>\n";
              }
            }
//  ============================== Sub Menu 1 Start ============================== //
      $msql1 = dbquery("SELECT * FROM ".DB_MENUS." WHERE menu_cat='".$mdata['menu_id']."' ORDER BY menu_order");
      if (dbrows($msql1) != 0) {
        echo "<ul class='sub'>";
        while ($mdata1 = dbarray($msql1)) {
          if (checkgroup($mdata1['menu_access'])) {                   
            $link_target = ($mdata1['menu_window'] == "1" ? " target='_blank'" : "");
              if(dbrows(dbquery("SELECT menu_cat FROM ".DB_MENUS." WHERE menu_cat='".$mdata1['menu_id']."'"))) {
              $link_class = " class='fly'";
              } else {
                $link_class = "";
              }
                if ($mdata1['menu_name'] !== "---" && $mdata1['menu_link'] == "---") {
                  echo "<li><b>".parseubb($mdata1['menu_name'], "b|i|u|left|center|right|img|color")."</b>\n";
                } else if ($mdata1['menu_name'] == "---" && $mdata1['menu_link'] == "---") {
                  echo "<li><hr />\n";
                } else {
                  if (preg_match("!^(ht|f)tp(s)?://!i", $mdata1['menu_link'])) {
                    echo "<li><a href='".$mdata1['menu_link']."'".$link_target."".$link_class.">".parseubb($mdata1['menu_name'], "b|i|u|left|center|right|img|color")."</a>\n";
                  } else {
                    echo "<li><a href='".BASEDIR.$mdata1['menu_link']."'".$link_target."".$link_class.">".parseubb($mdata1['menu_name'], "b|i|u|left|center|right|img|color")."</a>\n";
                  }
                }
//  ============================== Sub Menu 2 Start ============================== //
            $msql2 = dbquery("SELECT * FROM ".DB_MENUS." WHERE menu_cat='".$mdata1['menu_id']."' ORDER BY menu_order");
            if (dbrows($msql2) != 0) {
              echo "<ul>";
              while ($mdata2 = dbarray($msql2)) {
                if (checkgroup($mdata2['menu_access'])) {                   
                  $link_target = ($mdata2['menu_window'] == "1" ? " target='_blank'" : "");
                    if(dbrows(dbquery("SELECT menu_cat FROM ".DB_MENUS." WHERE menu_cat='".$mdata2['menu_id']."'"))) {
                    $link_class = " class='fly'";
                    } else {
                      $link_class = "";
                    }
                      if ($mdata2['menu_name'] !== "---" && $mdata2['menu_link'] == "---") {
                        echo "<li><b>".parseubb($mdata2['menu_name'], "b|i|u|left|center|right|img|color")."</b>\n";
                      } else if ($mdata2['menu_name'] == "---" && $mdata2['menu_link'] == "---") {
                        echo "<li><hr />\n";
                      } else {
                        if (preg_match("!^(ht|f)tp(s)?://!i", $mdata2['menu_link'])) {
                          echo "<li><a href='".$mdata2['menu_link']."'".$link_target."".$link_class.">".parseubb($mdata2['menu_name'], "b|i|u|left|center|right|img|color")."</a>\n";
                        } else {
                          echo "<li><a href='".BASEDIR.$mdata2['menu_link']."'".$link_target."".$link_class.">".parseubb($mdata2['menu_name'], "b|i|u|left|center|right|img|color")."</a>\n";
                        }
                      }
//  ============================== Sub Menu 3 Start ============================== //
                  $msql3 = dbquery("SELECT * FROM ".DB_MENUS." WHERE menu_cat='".$mdata2['menu_id']."' ORDER BY menu_order");
                  if (dbrows($msql3) != 0) {
                    echo "<ul>";
                    while ($mdata3 = dbarray($msql3)) {
                      if (checkgroup($mdata3['menu_access'])) {
                        $link_target = ($mdata3['menu_window'] == "1" ? " target='_blank'" : "");
                          if ($mdata3['menu_name'] !== "---" && $mdata3['menu_link'] == "---") {
                            echo "<li><b>".parseubb($mdata3['menu_name'], "b|i|u|left|center|right|img|color")."</b>\n";
                          } else if ($mdata3['menu_name'] == "---" && $mdata3['menu_link'] == "---") {
                            echo "<li><hr /></li>\n";
                          } else {
                            if (preg_match("!^(ht|f)tp(s)?://!i", $mdata3['menu_link'])) {
                              echo "<li><a href='".$mdata3['menu_link']."'".$link_target.">".parseubb($mdata3['menu_name'], "b|i|u|left|center|right|img|color")."</a></li>\n";
                            } else {
                              echo "<li><a href='".BASEDIR.$mdata3['menu_link']."'".$link_target.">".parseubb($mdata3['menu_name'], "b|i|u|left|center|right|img|color")."</a></li>\n";
                            }
                          }
//  ============================== Sub Menu 3 End ============================== //
                        }
                    }
                    echo "</ul>\n";
                  }
                  echo "</li>\n";
//  ============================== Sub Menu 2 End ============================== //
                }
              }
              echo "</ul>\n";
            }
            echo "</li>\n";
//  ============================== Sub Menu 1 End ============================== //
          }
        }
        echo "</ul>\n";
      }
      echo "</li>\n";
//  ============================== Main Menu End ============================== //
    }
  }
  echo "</ul>\n";
}

Jeg har ladet mig vide at det skulle være de 4 while løkker der laver de mange forespørgsler, men jeg kan desværre bare ikke se hvordan man evt. kan undlade dem - og så stadig at menuen virker.

Er her mon et skarpt hovede der kan hjælpe ?

Mvh.
Buxxy.
Avatar billede buxxy Praktikant
10. januar 2012 - 11:21 #1
OBS: Jeg undskylder mine 2 tidligere ens oprettede tråde, men den ville ikke tage mine point med. Det lykkedes så dog nu.
Avatar billede acore Ekspert
10. januar 2012 - 11:35 #2
Dine menuer er vel næppe så store, at de ikke kan rummes i hukommelsen.

En mulighed er - hvis man skal følge den idé - at starte med én query, hvor du henter alt i menuen ind i arrays.

Dine while skal så laves om til foreach efterfulgt at en if (menu_cat = xxx), der sørger for, at du kun processerer relevante items. Og indeholder så ikke nogle queries.

Er det forståeligt og brugbart - som koncept? I så fald kan vi arbejde videre med det.
Avatar billede buxxy Praktikant
10. januar 2012 - 12:30 #3
Hej acore.

Hmm, med mine nuværende menupunkter så trækker den menu alene 114 forespørgsler - det synes jeg er i overkanten, og det kan ligeså mærkes på sidens hastighed.

Hehe, nu er jeg langt fra den skarpeste kniv i skuffen til det her. Alene det jeg har fået skruet sammen indtil nu - ja det har taget mig på den anden side af et helt år. Det være sig ved utallige mange timers læsning/søgning, samt ikke mindst ca. en milliard forsøg på at få skidtet til at virke. Det har jeg så dog langt om længe opnået - men blot for at finde ud af at den bruger for mange queries.

Jeg ved ikke helt, jeg er nok ikke den rette til at svare på om dit forslag er brugbart, eftersom jeg ikke ved hvordan/hvad der skal gøres/hvordan det vil komme til at evt. virke.
Avatar billede acore Ekspert
10. januar 2012 - 19:22 #4
Årh. helt ueffen er du jo ikke - det ved jeg. For at forklare det bedre, så se denne kode. Den er IKKE færdig, men jeg har skrevet lidt ind, der bedre forklare ideen:

//  ============================== Main Menu Start ============================== //
$msql = dbquery("SELECT * FROM ".DB_MENUS." ORDER BY menu_order"); // Tag alt med
if (dbrows($msql) != 0) {
  while ($mdata = dbarray($msql)) {
    $m_id = $mdata['menu_id'];
    $m_cat[] = $mdata['menu_cat'];
    $m_access[] = $mdata['menu_access'];
    $m_window[] = $mdata['menu_window'];
    $m_link[] = $mdata['menu_link'];
    $m_name[] = $mdata['menu_name'];
    // ... tilføj dem der mangler
  }
  $n = count($m_id);

  echo "<ul id='nav'>";
  //while ($mdata = dbarray($msql)) {
  for ($i = 0; $i < $n; $i++) {
    if ($m_cat[$i] == 0 && checkgroup($mdata['menu_access'])) { // Her tilføjer jeg det kriterie jeg nu ikke har i SELECY
    // I al efterfølgende kode skal $mdata['xxx'] rettes til $m_xxx[$i]
      $link_target = ($mdata['menu_window'] == "1" ? " target='_blank'" : "");
        if(dbrows(dbquery("SELECT menu_cat FROM ".DB_MENUS." WHERE menu_cat='".$mdata['menu_id']."'"))) {
          $div_class = " class='down'";
          } else {
            $div_class = "";
          }
            if ($mdata['menu_name'] !== "---" && $mdata['menu_link'] == "---") {
              if (preg_match("!^(ht|f)tp(s)?://!i", $mdata['menu_link'])) {
                echo "<li class='top'><div".$div_class."><a href='".$mdata['menu_link']."'".$link_target." class='top_link'>".parseubb($mdata['menu_name'], "b|i|u|img|color")."</a></div>\n";
              } else {
                echo "<li class='top'><div".$div_class."><a href='".BASEDIR.$mdata['menu_link']."'".$link_target." class='top_link'>".parseubb($mdata['menu_name'], "b|i|u|img|color")."</a></div>\n";
              }
            } else if ($mdata['menu_name'] !== "---" && $mdata['menu_link'] == "") {
              if (preg_match("!^(ht|f)tp(s)?://!i", $mdata['menu_link'])) {
                echo "<li class='top'><div".$div_class."><a href='".$mdata['menu_link']."'".$link_target." class='top_link'>".parseubb($mdata['menu_name'], "b|i|u|img|color")."</a></div>\n";
              } else {
                echo "<li class='top'><div".$div_class."><a href='".BASEDIR.$mdata['menu_link']."'".$link_target." class='top_link'>".parseubb($mdata['menu_name'], "b|i|u|img|color")."</a></div>\n";
              }
            } else if ($mdata['menu_name'] == "---" && $mdata['menu_link'] == "---") {
              echo "<li class='top'><hr />\n";
            } else {
              if (preg_match("!^(ht|f)tp(s)?://!i", $mdata['menu_link'])) {
                echo "<li class='top'><div".$div_class."><a href='".$mdata['menu_link']."'".$link_target." class='top_link'>".parseubb($mdata['menu_name'], "b|i|u|img|color")."</a></div>\n";
              } else {
              echo "<li class='top'><div".$div_class."><a href='".BASEDIR.$mdata['menu_link']."'".$link_target." class='top_link'>".parseubb($mdata['menu_name'], "b|i|u|img|color")."</a></div>\n";
              }
            }
//  ============================== Sub Menu 1 Start ============================== //
      // $msql1 = dbquery("SELECT * FROM ".DB_MENUS." WHERE menu_cat='".$mdata['menu_id']."' ORDER BY menu_order"); Dne skal vi ikke bruge nu
      if (dbrows($msql1) != 0) {
        echo "<ul class='sub'>";
        //while ($mdata1 = dbarray($msql1)) {
        for ($i1 = 0; $i1 < $n; $i1++) {
          if ($m_cat[$i1] == $m_id[$i] && checkgroup($mdata1['menu_access'])) { // her tilføjes så udvælgelseskriteriet fra den andet SELECT
    // ...og $mdata1['xxx'] rettes til $m_xxx[$i1]
            $link_target = ($mdata1['menu_window'] == "1" ? " target='_blank'" : "");
              if(dbrows(dbquery("SELECT menu_cat FROM ".DB_MENUS." WHERE menu_cat='".$mdata1['menu_id']."'"))) { // Denne optælling kanogså laves direkte i data og uden SELECT
              $link_class = " class='fly'";
              } else {
                $link_class = "";
              }
                if ($mdata1['menu_name'] !== "---" && $mdata1['menu_link'] == "---") {
                  echo "<li><b>".parseubb($mdata1['menu_name'], "b|i|u|left|center|right|img|color")."</b>\n";
                } else if ($mdata1['menu_name'] == "---" && $mdata1['menu_link'] == "---") {
                  echo "<li><hr />\n";
                } else {
                  if (preg_match("!^(ht|f)tp(s)?://!i", $mdata1['menu_link'])) {
                    echo "<li><a href='".$mdata1['menu_link']."'".$link_target."".$link_class.">".parseubb($mdata1['menu_name'], "b|i|u|left|center|right|img|color")."</a>\n";
                  } else {
                    echo "<li><a href='".BASEDIR.$mdata1['menu_link']."'".$link_target."".$link_class.">".parseubb($mdata1['menu_name'], "b|i|u|left|center|right|img|color")."</a>\n";
                  }
                }
//  ============================== Sub Menu 2 Start ============================== //
            // $msql2 = dbquery("SELECT * FROM ".DB_MENUS." WHERE menu_cat='".$mdata1['menu_id']."' ORDER BY menu_order");
            if (dbrows($msql2) != 0) {
              echo "<ul>";
              // while ($mdata2 = dbarray($msql2)) {
              for ($i2 = 0; $i2 < $n; $i2++) {
                if ($m_cat[$i2] == $m_id[$i1] && checkgroup($mdata2['menu_access'])) {  // og her kriteriet fra den 3. SELECT
    // ...og $mdata2['xxx'] rettes til $m_xxx[$i2]
                  $link_target = ($mdata2['menu_window'] == "1" ? " target='_blank'" : "");
                    if(dbrows(dbquery("SELECT menu_cat FROM ".DB_MENUS." WHERE menu_cat='".$mdata2['menu_id']."'"))) {
                    $link_class = " class='fly'";
                    } else {
                      $link_class = "";
                    }
                      if ($mdata2['menu_name'] !== "---" && $mdata2['menu_link'] == "---") {
                        echo "<li><b>".parseubb($mdata2['menu_name'], "b|i|u|left|center|right|img|color")."</b>\n";
                      } else if ($mdata2['menu_name'] == "---" && $mdata2['menu_link'] == "---") {
                        echo "<li><hr />\n";
                      } else {
                        if (preg_match("!^(ht|f)tp(s)?://!i", $mdata2['menu_link'])) {
                          echo "<li><a href='".$mdata2['menu_link']."'".$link_target."".$link_class.">".parseubb($mdata2['menu_name'], "b|i|u|left|center|right|img|color")."</a>\n";
                        } else {
                          echo "<li><a href='".BASEDIR.$mdata2['menu_link']."'".$link_target."".$link_class.">".parseubb($mdata2['menu_name'], "b|i|u|left|center|right|img|color")."</a>\n";
                        }
                      }
//  ============================== Sub Menu 3 Start ============================== //
                  //$msql3 = dbquery("SELECT * FROM ".DB_MENUS." WHERE menu_cat='".$mdata2['menu_id']."' ORDER BY menu_order");
                  if (dbrows($msql3) != 0) {
                    echo "<ul>";
                    //while ($mdata3 = dbarray($msql3)) {
                    for ($i3 = 0; $i3 < $n; $i3++)
                      if ($m_cat[$i3] == $m_id[$i2] && checkgroup($mdata3['menu_access'])) { // Do her
    // ...og $mdata3['xxx'] rettes til $m_xxx[$i3]
                        $link_target = ($mdata3['menu_window'] == "1" ? " target='_blank'" : "");
                          if ($mdata3['menu_name'] !== "---" && $mdata3['menu_link'] == "---") {
                            echo "<li><b>".parseubb($mdata3['menu_name'], "b|i|u|left|center|right|img|color")."</b>\n";
                          } else if ($mdata3['menu_name'] == "---" && $mdata3['menu_link'] == "---") {
                            echo "<li><hr /></li>\n";
                          } else {
                            if (preg_match("!^(ht|f)tp(s)?://!i", $mdata3['menu_link'])) {
                              echo "<li><a href='".$mdata3['menu_link']."'".$link_target.">".parseubb($mdata3['menu_name'], "b|i|u|left|center|right|img|color")."</a></li>\n";
                            } else {
                              echo "<li><a href='".BASEDIR.$mdata3['menu_link']."'".$link_target.">".parseubb($mdata3['menu_name'], "b|i|u|left|center|right|img|color")."</a></li>\n";
                            }
                          }
//  ============================== Sub Menu 3 End ============================== //
                        }
                    }
                    echo "</ul>\n";
                  }
                  echo "</li>\n";
//  ============================== Sub Menu 2 End ============================== //
                }
              }
              echo "</ul>\n";
            }
            echo "</li>\n";
//  ============================== Sub Menu 1 End ============================== //
          }
        }
        echo "</ul>\n";
      }
      echo "</li>\n";
//  ============================== Main Menu End ============================== //
    }
  }
  echo "</ul>\n";
}
Avatar billede buxxy Praktikant
23. januar 2012 - 15:40 #5
Hej igen acore.

Nu har jeg virkelig givet det rigtig rigtig mange forsøg, men dog uden at kunne få det til at virke.

Jeg har derfor droppet at arbejde videre på menuen.

Du skal i hvert fald have mange tusind tak for dine inputs!

Hvis du smider et svar så kan vi lige afregne.

Fortsat god dag!

Mvh.
Buxxy.
Avatar billede acore Ekspert
24. januar 2012 - 22:17 #6
Arh, det var ærgerligt.
Avatar billede erikjacobsen Ekspert
24. januar 2012 - 23:16 #7
Et lille indspark: menuen behøver vel ikke blive genberegnet for hver side. Den ændrer sig vel ikke så tit...?

Hvad med at lave et særligt PHP-script, som beregner HTML-koden for menuen, og gemmer den i et LONGTEXT felt i databasen. Det hentes så op med eet SQL-kald.

Hver gang du har ændringer, som bevirker at menuen skal ændres, så kan du kan kalde scriptet igen.

Så er det egentlig lidt lige meget hvor lang tid det tager.
Avatar billede buxxy Praktikant
25. januar 2012 - 00:45 #8
@ej: Hmm, jeg må desværre melde klart ud at jeg ikke ved hvad du mener - jeg kan kun copy/paste mht. koderiet.

Men du skal også have mange tusind tak for dit input.

Tror jeg holder en pause nu fra alt det her "skidt" - har sgu været i gang så længe nu, at jeg nærmest føler at hovedet er ved at "poppe af"....  ;-)

Anyway - så mange tak til Jer begge to!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester