MySQL Query dauert über PHP sehr viel länger als über PHPmyAdmin
Günther S
- datenbank
Hallo zusammen,
ich habe eine MySQL-Tabelle mit 6 Spalten und rund 70.000 Datensätzen darin.
Es geht um folgenden Query:
SELECT id, user_id FROM comments ORDER BY datum DESC
Wenn ich diesen Query in PHP via mysql_query() ausführen lasse, dauert das ca. 1 Sekunde, also sehr lange (nur das ausführen selbst, ich habe alles drum rum schon auskommentiert).
Ich habe mal den Query von PHP mittels var_dump ausgeben lassen und hab das direkt vom Browser in PHPmyAdmin kopiert.
Dort habe ich wie gewünscht die ca. 70.000 Ergebnisse bekommen und zwar in 0.02 Sekunden.
Woran kann das liegen?
Gruß,
Günther
hi,
Ich habe mal den Query von PHP mittels var_dump ausgeben lassen und hab das direkt vom Browser in PHPmyAdmin kopiert.
Dort habe ich wie gewünscht die ca. 70.000 Ergebnisse bekommen und zwar in 0.02 Sekunden.
PMA zeigt doch nicht alle Datensätze auf einmal an, sondern schränkt mittels LIMIT die Ergebnismenge ein - oder hast du irgendwo explizit angegeben, dass PMA dir alle Ergebnisse auf einer Seite anzeigen soll?
gruß,
wahsaga
Hi wahsaga!
Ich muss dir mal ein Kompliment aussprechen. Deine Antworten sind immer wohl durchdacht und zeugen von Kompetenz.
Ich weiß nicht, wie du es machst, aber wo ich (und sicher viele andere auch) lange grübeln, wo der Fehler liegt, kommst du und knallst die Lösung auf den Tisch.
Du hast meinen tiefsten Respekt.
MfG H☼psel
hi,
Ich weiß nicht, wie du es machst, aber wo ich (und sicher viele andere auch) lange grübeln, wo der Fehler liegt, kommst du und knallst die Lösung auf den Tisch.
Woll'n wir vorm Lobhudeln nicht erst mal abwarten, ob das auch wirklich die "Erklärung des Phänomens" ist ...?
gruß,
wahsaga
Hallo,
Ich weiß nicht, wie du es machst, aber wo ich (und sicher viele andere auch) lange grübeln, wo der Fehler liegt, kommst du und knallst die Lösung auf den Tisch.
Das Kompliment kann ich nur bestätigen :)
Woll'n wir vorm Lobhudeln nicht erst mal abwarten, ob das auch wirklich die "Erklärung des Phänomens" ist ...?
Ist es.
Gruß,
Günther
Hallo,
Ich habe mal den Query von PHP mittels var_dump ausgeben lassen und hab das direkt vom Browser in PHPmyAdmin kopiert.
Dort habe ich wie gewünscht die ca. 70.000 Ergebnisse bekommen und zwar in 0.02 Sekunden.PMA zeigt doch nicht alle Datensätze auf einmal an, sondern schränkt mittels LIMIT die Ergebnismenge ein - oder hast du irgendwo explizit angegeben, dass PMA dir alle Ergebnisse auf einer Seite anzeigen soll?
... Manchmal sieht man den Wald vor lauter Bäumen nicht. Daran lag's, richtig ;)
Damit stoße ich allerdings auf ein anderes Problem:
Es handelt sich, wie der Tabellenname schon sagt, um Kommentare. Von diesen soll eine Teilmenge 'seitenweise' auf der Website angezeigt werden.
Es würde mir also reichen, je 20 - 30 Kommentare aus dieser Teilmenge der Tabelle auf einmal auswählen zu lassen.
Doch zuvor muss ich wissen, wie viele Seiten es gibt, um bewerten zu können, ob die vom Benutzer angeforderte Seite überhaupt gültig ist (was ist, wenn der User mittels Direkteingabe in der URL als Seitennummer eine viel zu hohe Zahl eingibt?).
Das wird aber wohl nicht funktionieren, ohne zu wissen, wie viele Elemente zu dieser Teilmenge der Tabelle gehören ("WHERE typ = '...'"). (Falls doch, bin ich sehr dankbar für Denkanstöße)
Gibt es irgendeine Möglichkeit, das herauszufinden, ohne den Query explizit auszuführen?
SELECT COUNT(*) FROM comments WHERE ...
dauert ähnlich lange, fällt also leider auch weg.
Klar kann man die Tabelle indizieren (werde ich auch noch machen), aber ich hätte lieber eine Lösung, die das Problem "an den Wurzeln" packt.
Gruß,
Günther
Hi Günther!
Gibt es irgendeine Möglichkeit, das herauszufinden, ohne den Query explizit auszuführen?
Wenn du mit LIMIT StartEintrag, AnzahlDerEinträge
auf die Einträge zugreifst, gibt es kein Problem. Du musst nur eventuell überprüfen, ob überhaupt ein Eintrag ausgelesen wurde.
MfG H☼psel
hi,
Gibt es irgendeine Möglichkeit, das herauszufinden, ohne den Query explizit auszuführen?
Nein. Wenn du was von der Db wissen willst, musst du sie danach fragen.
SELECT COUNT(*) FROM comments WHERE ...
> dauert ähnlich lange, fällt also leider auch weg.
>
> Klar kann man die Tabelle indizieren (werde ich auch noch machen), aber ich hätte lieber eine Lösung, die das Problem "an den Wurzeln" packt.
Sinnvoll Indizes zu setzen, packt Datenbankprobleme an der Wurzel.
Indizes sind integraler Bestandteil eines guten Datenbankdesigns, auf sie zu verzichten, wäre also unsinnig.
Wenn du LIMIT nutzt, um für eine Blätterfunktion nur jeweils X Einträge pro Seite auszulesen, schau dir auch mal [FOUND_ROWS()](http://dev.mysql.com/doc/refman/4.1/en/information-functions.html) an - das kann dir unter Beibehaltung der LIMIT-Einschränkung trotzdem noch mitteilen, wie viele Ergebnisse die Query ohne LIMIT gebracht hätte.
gruß,
wahsaga
--
/voodoo.css:
#GeorgeWBush { position:absolute; bottom:-6ft; }
Hallo,
Wenn du LIMIT nutzt, um für eine Blätterfunktion nur jeweils X Einträge pro Seite auszulesen, schau dir auch mal FOUND_ROWS() an - das kann dir unter Beibehaltung der LIMIT-Einschränkung trotzdem noch mitteilen, wie viele Ergebnisse die Query ohne LIMIT gebracht hätte.
Das ist zwar nicht ganz das, was ich gerne gehabt hätte, aber immerhin kann man im Normalfall (DAU gibt keine unsinnige Seitennummer ein) auf den sehr zeitintensiven Query verzichten und diesen nur dann ausführen, falls das nötig ist (FOUND_ROWS() == 0).
Daher, danke!
Gruß,
Günther
Das ist zwar nicht ganz das, was ich gerne gehabt hätte, aber immerhin kann man im Normalfall (DAU gibt keine unsinnige Seitennummer ein) auf den sehr zeitintensiven Query verzichten und diesen nur dann ausführen, falls das nötig ist (FOUND_ROWS() == 0).
Eventuell mal einen Index auf das DF 'datum' setzen und eventuell mal prüfen, ob Du die Anzahl der Datensätze in einer Tabelle bei MySQL nicht auch herausbekommst ohne ein SELECT auf die gesamte Tabelle (mit oder ohne LIMIT) zu machen, bspw. über Systemtabellen oder Systemsichten...
BTW - kennst Du den DAE?
Das ist zwar nicht ganz das, was ich gerne gehabt hätte, aber immerhin kann man im Normalfall (DAU gibt keine unsinnige Seitennummer ein) auf den sehr zeitintensiven Query verzichten und diesen nur dann ausführen, falls das nötig ist (FOUND_ROWS() == 0).
Das ist falsch, FOUND_ROWS gibt dir nicht an wieviele Zeilen deine Abfrage hat, sondern wieviele Zeilen deine Abfrage ohne LIMIT hätte.
Was du meinst ist die Anzahl der Zeilen deiner Abfrage, die kann man ohne Probleme ermitteln (ich kann kein PHP, aber es gibt eine Funktion mysql_rows() oder so ähnlich) ausserdem wird die Schleife mit der du die Daten abfragst in dem Falle nicht ausgeführt, da die abfrage bei rows=0 leer ist.
du kannst mit FOUND_ROWS() ohne die Abfrage erneut auszuführen, die Anzahl der tasächlichen Zeilen deiner Abfrage ermitteln um damit eine "Blätternfunktion" umzusetzen.
Struppi.
hi,
Was du meinst ist die Anzahl der Zeilen deiner Abfrage, die kann man ohne Probleme ermitteln (ich kann kein PHP, aber es gibt eine Funktion mysql_rows() oder so ähnlich)
Genau, mysql_num_rows.
gruß,
wahsaga