Autor Zpráva
kchrz
Profil
Zdravím!
Potřeboval bych radu, jak optimalizovat výpis z mysql tabulky. Skript mi funguje, ale je napsaný hodně kostrbatě a při více jak 500 řádcích v tabulce už pár vteřin trvá, než se stránka načte. evidentě jsem na to šel příliž zbytečně složitě. Pokusím se popsat polopatě, o co mi jde.
Skript běží pod wordpressem.

Mám 2 tabulky, viz obrázek.

Z tabulky ČELEDĚ načtu první řádek, id a text. Nakouknu do tabulky RYBY, pokud obsahuje řádek s příslušnou čeledí a současně splňuje podmínku ZOBRAZIT, pak
- vypíše řádek s tabulky ČELEDĚ a následně x řádků splňujících podmínku čeleď a zobrazeno.
- pokud tabulka ryby nebosahuje řádky s příslušnou čeledí, nebo ano ale s nulovým zobrazeno, !nevypíše se ani příslušná čeleď. Zkrátka, aby nevyběhla tabulka bez řádků.

$db = mysqli_connect($dbServer,$dbUser,$dbPass,$dbDatabase) or die("Není možné připojit databázový server.");

$cislo = mysqli_query($db,"SELECT * FROM $celed ORDER BY celed_id DESC LIMIT 1");
while( $rowen = mysqli_fetch_array($cislo)){ $maxIDceled = $rowen["celed_id"]; }
// zjistí, kolik řádků je v tabulace

$cislo = mysqli_query($db,"SELECT * FROM $ryby ORDER BY id DESC LIMIT 1");
while( $rowen = mysqli_fetch_array($cislo)){ $maxIDryby = $rowen["id"]; }
// zjistí, kolik řádků je v tabulace

    for($x=1; $x<=$maxIDceled; ++$x) { // vypíše cyklus řádků v tabulce čeledě. 
        $result = mysqli_query($db,"SELECT * FROM $celed WHERE celed_id = '$x' ");
        while( $row = mysqli_fetch_array($result)){ $nadpis_pred_tabulkou = $row["celed_text"];  }  // Uloží si nadpis aktuálního řádku čeledě
                                                                                               
                for($a=1; $a<=$maxIDryby; ++$a) { // vypíše cyklus řádků v tabulce ryby
        
                $result = mysqli_query($db,"SELECT * FROM $ryby WHERE celed = '$x' AND  id = '$a' AND zobrazit='1' ");
                while( $row = mysqli_fetch_array($result)){ 
                echo "<H2>$nadpis_pred_tabulkou </H2>"; // pakliže jsou v dané čeledi položky ryby, vypíše nadpis Čeledi, pod kterou se ryby budou vypisovat. Pokud ne, tak na konci vyklu Break2 a celá čáast i s nadpisem se přeskočí
                
                for($a=1; $a<=$maxIDryby; ++$a) { // vypíše cyklus řádků v tabulce ryby 
                       $result = mysqli_query($db,"SELECT * FROM $ryby WHERE celed = '$x' AND  id = '$a' AND zobrazit='1' ");
                   while( $row = mysqli_fetch_array($result)){  .... výpis řádků tabulky Ryby }
               }
            Break 2;
            }}}



Výsledek vypadá takhle, ale je to kostrbaté a hlavně pomalé. - zoo.lf1.cz/ryby

Díky moc za rady
Kajman
Profil
Asi bych to udělal jedním dotazem, viz Srovnání dotazů do závislých tabulek
SELECT c.celed_text,
       r.*
FROM   `$ryby` r
       JOIN `$celed` c
         ON r.celed = c.celed_id
WHERE  r.zobrazit = 1
ORDER  BY c.celed_text,
          r.celed,
          r.latinsky,
          r.id 

Stačí jediný dotaz, plus si budete pamatovat poslední vypsanou čeleď a pokud se různí, vypíšete před rybou i nadpis.
Viz Nejčastější potíže s PHP (FAQ) » Nadpis skupiny nejen při výpisu z databáze

Kdyby ten dotaz byl pomalý, zkuste udělat index nad sloupcem zobrazit.
kchrz
Profil
Děkuji za odpověď.
upravil jsem dle pokynů a zdá se že funguje.
Jen prosím o kontrolu, jestli to bylo myšleno takto.
každopádně díky.

Mám tam jen jeden problém, nedaří se mi někam vložit ukončení tabulky. nemůžu přijít, jak ho tam vložit.

$result = mysqli_query($db,"SELECT c.celed_text,
               r.*
        FROM   `$ryby` r
               JOIN `$celed` c
             ON r.celed = c.celed_id
        WHERE  r.zobrazit = 1
        ORDER  BY c.celed_text,
            r.celed,
              r.latinsky,
              r.id  ");
              
              $pamet = '';
        while( $row = mysqli_fetch_array($result)){ 
                
           if ($row['celed_text'] != $pamet)
              {
              $pamet = $row['celed_text'];
                echo "<br><br><b>$pamet</b><br>";
                echo "<table class=tablesorter><thead><tr><th>latinsky</th><th>cena</th></tr></thead><tbody>";
          }
         echo "<tr><td>$row[latinsky] </td><td> $row[cena] ,- Kč </td></tr>";                
            }



Vymyslel jsem to s tou tabulkou jen takhle, ale přijde mi to trochu prasárna. Protože nahoře mám tím pádem neviditelnou tabulku bez řádků

$pamet = '';
             $pamet2 = '';
             echo "<table>";
        while( $row = mysqli_fetch_array($result)){ 
        
        if ($row['celed_text'] != $pamet2)
              { $pamet2 = $row['celed_text']; echo "</table>";  }
                
           if ($row['celed_text'] != $pamet)
              {      $pamet = $row['celed_text'];
                    echo "<b>$pamet</b></br></br>";
                     echo "<table><tr><td>latinsky</td><td>cena</td></tr>";      }
                     
         echo "<tr><td>$row[latinsky] </td><td> $row[cena] ,- Kč </td></tr>";                                             
        }
        echo "</table>";
Kajman
Profil
Můžete si udělat čítač čeledí a podle toho tabulku ukončovat...

$minula_celed = false;
$pocet_celedi = 0;
while( $row = mysqli_fetch_array($result)) { 
    //zmenila se celed? (jistejsi je testovat id)
    if ($row['celed'] !== $minula_celed) {
            //zvysim pocitadlo nadpisu
        $pocet_celedi++;
        //neni to prvni?
        if($pocet_celedi>0) {
            echo "</table>";
        }
        //zapamatuji si celed pro porovnani v dalsim radku
        $minula_celed = $row['celed'];
        //vypisu hlavicku celedi
        echo "<b>".htmlspecialchars($row['celed_text'])."</b></br></br>";
        echo "<table><tr><td>latinsky</td><td>cena</td></tr>";      
    }
    // jedna rybka
    echo "<tr><td>".htmlspecialchars($row['latinsky'])."</td><td>".htmlspecialchars($row['cena'])." ,- Kč </td></tr>";                                             
}
// byla alespon jedna celed
if($pocet_celedi>0) {
    echo "</table>";
}

A pokud to píšete pro wordpress, nemusíte se připojovat, stačí používat globální proměnnou $wpdb a její metody
codex.wordpress.org/Class_Reference/wpdb
kchrz
Profil
Funguje to. A hlavně, oproti původnímu několikastupňovému dotazu do MySQL, je to neskutečně rychlejší.
Takže ještě jednou díky moc.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0