• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

Bottleneck bei Datenbank-Abfrage finden

HanZ

Bekannter NGBler

Registriert
16 Juli 2013
Beiträge
1.061
Hallo,

ich habe eine Webseite, die beim Absenden eines Formulars eine Datenbankabfrage macht und das Ergebnis direkt auf der Webseite dann darstellt. Man kann nach bestimmten Kriterien filtern. Bei einer Abfrage nach dem kompletten Inhalt benötigt die Webseite ca. 7 Sekunden, bei einer Abfrage mit nur wenigen Ergebnissen ist das Ergebnis sofort da.
Ich bin bisher davon ausgegangen, dass einfach der Datenbestand zu groß ist (ca 3300 Einträge), die alle mit Einträgen aus einer 60.000 Inhalten umfassenden Tabelle verknüpft werden. Wenn ich aber die SQL-Abfrage direkt in der Konsole ausführe, dauert es nur 0.01 Sekunden

Es gibt 2 Tabelle:
- haupt
- merkmale

In "haupt" sind ca. 3300 Datensätze mit je grob 10 Spalten. Jeder einzelne Eintrag dort wird mit ca. 10 - 30 Datensätzen aus der Tabelle "merkmale" verknüpft (anhand der ID). Die Abfrage dazu lautet ca. so:

Code:
SELECT ID, abc, cde, fgh, (...), Group_Concat(merkmale SEPARATOR ', ' ) AS merkmale FROM haupt, merkmale WHERE haupt.ID=merkmale.ID GROUP BY haupt.ID;

Mit PHP frage ich das wie folgt ab:
Code:
try
    {
        $db = new PDO(...);
    }
    catch(PDOException $e)
    {
        throw new Exception($e->getMessage());
    }

Die Tatsache, dass die Abfrage auf der Konsole so schnell geht, lässt mich vermuten, dass die lange Wartezeit an was anderem liegt, vermutlich PHP?
Auch direkt im Netzwerk auf dem Server (192..../website) geht es nicht schneller.

Am Ende der Abfrage wird aus dem in PHP gefüllten Array jeder Eintrag (foreach Schleife) mit 'echo' auf die Webseite in eine <table> geschrieben.

Wie gehe ich hier denn vor, um am besten rauszufinden, wieso die Abfrage so lange dauert? Oder hat schon jemand direkt eine Idee?

LG
HanZ
 
Zuletzt bearbeitet:

one

Querulant

Registriert
21 Juli 2013
Beiträge
6.003
Ort
ja
Habs da momentan nicht so mit. Aber verstehe/interpretiere ich dass richtig, dass beim Einlesen immer alle Datensätze abgefragt werden und nicht nur die neuen?

Dann haste dein Problem. Je mehr, desto Schnecke.
 

HanZ

Bekannter NGBler

Registriert
16 Juli 2013
Beiträge
1.061
  • Thread Starter Thread Starter
  • #3
Wieso schreibst du "einlesen"? Ich frage ja ab. Und wie ich schon geschrieben habe, dauert die Abfrage ja direkt auf der Kommandozeile nur ein Bruchteil einer Sekunde. Ich glaube also nicht, dass das Problem DB-bezogen ist.
 

one

Querulant

Registriert
21 Juli 2013
Beiträge
6.003
Ort
ja
Na Tabelle liest die ja ein.

War nur ein Gedanke.
 

dexter

Cloogshicer®
Teammitglied

Registriert
14 Juli 2013
Beiträge
5.441
Ich bin da auch nich so schlau, aber ich würde mir auf Verdacht mal debug-fehler ausgeben lassen. Am Ende is das PHP 7 Sekunden lang mit Fehlern und oder fallbacks beschäftigt.
Klingt komisch, is aber nich auszuschliessen.
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Hallo @HanZ :
Das klingt für mich danach, als ob wirklich das bauen der Tabelle im HTML das Bottleneck ist.

Wenn die DB Abfrage mit gleichen Parametern in PHPmyAdmin oder von der Kommandozeile nur ein paar Sekunden braucht, liegt die Vermutung nah, dass es bei der Aufbereitung der Daten hapert.

Welche PHP Version hast du den aktuell in Verwendung Client/Server? Und kannst du den Code posten, der die Tabelle aufbaut?
 

KingJamez

Aktiver NGBler

Registriert
18 Juli 2013
Beiträge
505
Braucht PHP lange oder ist es dein browser, dass dir mal zeiten ausgeben, das du überhaupt weißt was lange braucht.
 

HanZ

Bekannter NGBler

Registriert
16 Juli 2013
Beiträge
1.061
  • Thread Starter Thread Starter
  • #8
Welche PHP Version hast du den aktuell in Verwendung Client/Server? Und kannst du den Code posten, der die Tabelle aufbaut?
PHP 7.4 auf einer Synology mit MariaDB10. Der Code ist recht banal:
Code:
if ($select->rowCount() > 0)
    {
        echo ':<table id="table">
        <tr>
            <th>abc</th>
            <th>cde</th>
</tr>';
        foreach ($elements as $elem)
        {
            echo '<tr>
            <td>' . $elem["id"] . '</td>' . 
            '<td>' . $elem["merkmale"] . '</td></tr>';
        }
        echo '<table>';

Das hier ist das zuständige Javascript:
Code:
            window.addEventListener("DOMContentLoaded", function() {
                
                document.getElementById("anzeigen").addEventListener("click", function () {
                    
                    const xhr = new XMLHttpRequest();
                    xhr.open("POST", "antwort.php");
                    let daten = new FormData(document.getElementById("form"));
                    xhr.send(daten);
                    xhr.onreadystatechange = function () {
                        
                        if (xhr.readyState == 4 &&
                        xhr.status == 200) {
                            document.getElementById("ausgabe").innerHTML = xhr.responseText;
                        }
                    }
                });
            });



Ich habe mal auf meinen Handy die Abfrage auf der Webseite ausgeführt. Dort dauert es 14 Sekunden. Ich gehe also stark davon aus, dass es der Aufbau der Webseite ist, was meint ihr?
Gibt es da Möglichkeiten, die Zeiten zu reduzieren?
 

dexter

Cloogshicer®
Teammitglied

Registriert
14 Juli 2013
Beiträge
5.441
Ich habe mal auf meinen Handy die Abfrage auf der Webseite ausgeführt. Dort dauert es 14 Sekunden. Ich gehe also stark davon aus, dass es der Aufbau der Webseite ist, was meint ihr?
Erst mal schauen, ob das wirklich so is. ->Entwicklerkonsole vom Browser->Netzwerktab
Edit: Debug-log dort is auch manchmal ganz hilfreich
 

KingJamez

Aktiver NGBler

Registriert
18 Juli 2013
Beiträge
505
Über wie viele Einträge reden wir hier, wie viel muss der Browser rendern - evtl reicht eine pagination?
Könntest du vielleicht mal alles zur verfügung stellen? Im JS steht ein "getElementById('anzeigen')" was aber in deinem HTML nicht repräsentiert ist.
time:
<?php
    
$start = time();

//.. query

$end = time() - $start;
echo $end;
 

HanZ

Bekannter NGBler

Registriert
16 Juli 2013
Beiträge
1.061
  • Thread Starter Thread Starter
  • #11
Erst mal schauen, ob das wirklich so is. ->Entwicklerkonsole vom Browser->Netzwerktab
In der Entwicklerkonsole wird noch das Absenden des Formulars vermerkt, danach aber nichts mehr. Interessant: Wenn ich das Formular absende und direkt anschließend z.B. die Entwicklerkonsole aufrufe oder das Fenster auf z.B. Vollbild schalten möchte, macht er das erst, wenn die Abfrage zurückkommt. Ein weiteres Indiz, dass der Browser also das Bottleneck ist, da er erst alles parsen muss.


Über wie viele Einträge reden wir hier, wie viel muss der Browser rendern - evtl reicht eine pagination?
Aktuell 3360 Zeilen bei 15 Spalten. Pagination ist vermutlich keine Option, da dafür ja dennoch alles geparsed werden muss oder? Und halt nur die Anzeige anders dargestellt wird.

Könntest du vielleicht mal alles zur verfügung stellen? Im JS steht ein "getElementById('anzeigen')" was aber in deinem HTML nicht repräsentiert ist.
Sorry vergessen, das "anzeigen" ist lediglich der Absenden-Button:
Code:
<p class="input">
	<input type="reset" value="Zurücksetzen/Reset">
	<input type="button" value="Anzeigen/Show" id="anzeigen" />
</p>

Beim time-counter kommt nur 0 zurück. Wie vermutet.


Gibt es denn eine elegante Lösung, beim Absenden bis zur Darstellung der Daten einen Ladekreis/-balken o.ä. darzustellen? Die Wartezeit selbst empfinde ich nicht als das Problem, es wird in der Regel auf der Seite nur einmal alles abgefragt, danach wird sehr spezifisch gefiltert.
 

KingJamez

Aktiver NGBler

Registriert
18 Juli 2013
Beiträge
505
Ich glaube du solltest dich weniger um die optik kümmern (Ladebalken) sondern eher um die Performance ;).

Was sagen denn die Devtools > Netzwerk zur Größe die Transportiert wurde, steht ganz unten (in chrome - basierenden browsern)?

50k einträge ist nicht wenig, aber auch nicht so viel das der browser sich aufhängen sollte. Mit Paginierung meinte ich keine clientseitige paginierung sondern die Verwendung von offset limit in SQL.

Du kannst natürlich einen Ladebalken anzeigen, dann brauchst du halt ajax zum abfragen.
 

dexter

Cloogshicer®
Teammitglied

Registriert
14 Juli 2013
Beiträge
5.441
In der Entwicklerkonsole wird noch das Absenden des Formulars vermerkt, danach aber nichts mehr. Interessant: Wenn ich das Formular absende und direkt anschließend z.B. die Entwicklerkonsole aufrufe oder das Fenster auf z.B. Vollbild schalten möchte, macht er das erst, wenn die Abfrage zurückkommt. Ein weiteres Indiz, dass der Browser also das Bottleneck ist, da er erst alles parsen muss.
Das Netzwerktab muss zumindest im FF vor irgendeiner Aktion aufsein. Wenn Du keinen 2. Monitor für sowas haben solltest, kann man das auch andocken.
Du kannst auch anders (oder zusätzlich) rausfinden, ob der Browser das Prob ist. Einfach die selbe Seite statisch im Web (und vlt. zum Vergleich auch lokal) speichern, aufrufen und kucken was passiert.

Edit: Mit so nem Ladebalken hast Du garnix geschafft. Du weisst nicht, wo das Prob herkommt und der User weiss nicht, warum man mit DSL überall so bescheuerte Ladebalken sieht.
 

HanZ

Bekannter NGBler

Registriert
16 Juli 2013
Beiträge
1.061
  • Thread Starter Thread Starter
  • #14
Was sagen denn die Devtools > Netzwerk zur Größe die Transportiert wurde, steht ganz unten (in chrome - basierenden browsern)?
So sieht das Dev-Tool nach Abfrage der Daten aus:
Unbenannt.png


50k einträge ist nicht wenig, aber auch nicht so viel das der browser sich aufhängen sollte.
Im Endeffekt sind es nur 3360 Einträge. Die 50k Einträge sind jeweils ein dreistelliger Zahlencoder, der dann in einer Spalte als zusammenhängender String dargestellt wird, also quasi : "123, 456, 789"

Mit Paginierung meinte ich keine clientseitige paginierung sondern die Verwendung von offset limit in SQL.
Also dass nur ein Teil der Daten abgefragt wird? Ungerne, mit der gesamten Abfrage sollen ja auch alle Dateien angezeigt werden.

Du kannst auch anders (oder zusätzlich) rausfinden, ob der Browser das Prob ist. Einfach die selbe Seite statisch im Web (und vlt. zum Vergleich auch lokal) speichern, aufrufen und kucken was passiert.
Guter Hinweis. Wenn ich die Seite als .mhtml/.html abspeichere und sie dann öffne, benötigt es exakt die gleichen 6-7 Sekunden, bis der Ladebalken verschwindet. Scheint wohl also tatsächlich an der Dokumentgröße zu liegen.
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Versuch mal das hier anstelle des Echos für den Aufbau der Tabelleinhalte in der ForEach-Schleife:
PHP:
printf('<tr><td>%d</td><td>%s</td></tr>%s', $elem['id'], $elem['merkmale'], PHP_EOL);

Ich weiß nicht 100% ob das ein Gewinn ist, aber es wäre einen Versuch wert.. :)
 

RedlightX

Bekannter NGBler

Registriert
18 Juli 2013
Beiträge
1.185
Gerade bei solchen Datenmengen macht es m.E. durchaus Sinn. mit JSON zu arbeiten und das im Frontend zusammenzubauen (Hallo, Vue).
3/4 der zurückgelieferten Daten sind im Grunde nicht relevant, kosten aber Performance.
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Was mir noch einfällt, von welcher Datenmenge reden wir hier? Also wie viel MB hat die ausgegebene HTML Datei?
 

HanZ

Bekannter NGBler

Registriert
16 Juli 2013
Beiträge
1.061
  • Thread Starter Thread Starter
  • #18
@theSplit: printf bringt leider nichts, hab sogar eher das Gefühl, dass es noch ein Ticken länger dauert.

Die abgespeicherte .html/.mhtml hat ca. 7MB Dateigröße.


@RedlightX: Hast vermutlich Recht, PHP/JS/SQL ist leider nicht mein Expertengebiet, daher bin ich echt schon froh, dass das inzwischen alles so klappt wie ich es mir vorstelle :)
 

X-Coder

Aktiver NGBler

Registriert
14 Juli 2013
Beiträge
149
Wenn dein Browser zu lange zum rendern der lokal abgespeicherten Tabelle benötigt, ist es ein clientseitiges Bottleneck -> zuwenig Leistung / oder irgendeine Browser Extension welche das rendern ausbremst. Wenn die Entwicklerkonsole offen ist, bremst diese auch manchmal etwas aus.
Hast du mal verschiedene Browser durch probiert?

Warum kommt pagination für dich nicht in Frage?
Ich würde z.B. auch direkt so ewtas wie datatables einsetzen, am besten direkt Server-seitig per Ajax über json, wenn du zuviele Daten hast -> dann hättest du u. a. Suche, Pagination etc. gleich alles mit dabei.
 
Zuletzt bearbeitet:

dexter

Cloogshicer®
Teammitglied

Registriert
14 Juli 2013
Beiträge
5.441
Zufällig mal wieder hier reingestolpert, gibt es denn eine Auflösung des Problems?
 
Oben