Avatar

Performance enhancements? (General)

by Auge ⌂, Monday, December 30, 2013, 23:03 (3760 days ago) @ Wima

Hallo

Wie und womit führts du die Datenbankoptimierung durch? Worin zeigt sich der beobachtete Unterschied?


Ich mache das mit PhpMyAdmin, wie von Wendell weiter unten beschrieben. Einen Unterschied konnte ich allerdings nicht feststellen.

Hast du Daten bezüglich des Overheads/Überhangs vor der Optimierung?

Deine Beobachtung, dass die Datenstruktur in mlf1 schneller ist, zeigt sich wie? Kannst du das bitte – zusätzlich zu den obigen Fragen – auch noch einmal beschreiben?


In mlf1 erscheinen die Seiten in der Regel sofort, ohne bemerkbare Verzögerung. bei mlf2 gibt es oft eine Verzögerung von ein paar Sekunden. Das können auch mal 10 - 20 Sekunden sein.

Ich habe in den Skripten und in der Datenbank meiner Testinstallation (vergleichsweise armselige 12 Beiträge) bis jetzt nichts gefunden, was diese Wartezeiten erklären könnte. Der einzige Grund, der mir durch den Kopf schwirrt, ist die Art der Datenbankabfragen, wie ich ihn schon ansatzweise beschrieb.

Während in mlf1 die Daten zu Postings zumindest teilweise in zwei Schritten aus der Datenbank geholt werden (Schritt 1: lade das Posting, Schritt 2: lade, so es sich um das Posting eines registrierten Benutzers handelt, die Daten aus der Benutzertabelle), wird dies in mlf2 in einem Schritt erledigt (lade das Posting, prüfe, ob es zu diesem Posting Daten zum Benutzer in der Benutzertabelle gibt und lade diese, falls die Prüfung zutrifft). Dass das bei ungünstig gesetzten Indizes länger dauern kann, da die Datenbankengine bei vielen Einträgen länger zur Suche braucht, mag sein. Ich kann mir aber so ohne weiteres nicht vorstellen, dass das bis zu 20 Sekunden dauert.

Gucken wir mal rein. Die Benutzertabelle hat nur einen Index, nämlich die user_id. Im weiteren Verlauf wird das noch wichtig. Erstmal ist die index.inc.php dran. Die Queries stammen aus dieser Datei und sind von PHP-Sprenkeln befreit, umformatiert. Der direkte Aufruf per mysql_query wird jeweils weggelassen.

In der index.inc.php, die alle Threads listet, werden die Daten folgendermaßen abgefragt. Nach der Ermittlung, ob es Kategorien gibt und ob eine ausgewählt wurde, werden die Threads, die ausgegeben werden sollen, ermittelt.

SELECT
id,
tid
FROM mlf_entries
WHERE category = 3 AND pid = 0 AND spam = 0
ORDER BY sticky DESC, TIME DESC
LIMIT 30, 30

Die auszulesenden Felder id und tid als auch zwei der Felder, nach denen gefiltert werden soll, nämlich category und pid, haben Indizes. Das sollte also keine Probleme heraufbeschwören.

In einer Schleife werden nun pro Durchlauf für jeden der gefundenen Threads die Daten aller jeweils zugehörigen Postings gesucht (Zeile 87).

SELECT
id,
pid,
tid,
mlf_entries.user_id,
user_type,
UNIX_TIMESTAMP(TIME) AS TIME,
UNIX_TIMESTAMP(TIME + INTERVAL 60 MINUTE) AS TIMESTAMP,
UNIX_TIMESTAMP(last_reply) AS last_reply,
name,
user_name,
subject,
IF(text='', TRUE, FALSE) AS no_text,
category,
views,
marked,
locked,
sticky,
spam
FROM mlf_entries
LEFT JOIN mlf_userdata ON mlf_userdata.user_id = mlf_entries.user_id
WHERE tid = 7410 AND spam = 0
ORDER BY TIME ASC

Im JOIN wird geprüft, ob die user_id übereinstimmt. Diese ist, wie oben geschrieben, mit einem Index versehen. Auch die Filterbedingung (Feld tid) hat nach wie vor einen Index. Ob es sinnvoll ist, auch die anderen Felder, nach denen eventuell gefiltert werden soll (z.B. das Feld spam), mit einem Index zu versehen, vermag ich nicht zu beurteilen.

Danach erfolgen bei eingeschalteter Funktion noch Abfragen für die letzten Postings, die Tagcloud sowie für Admins und Moderatoren die mutmaßlichen Spampostings. Der Query für die letzten Postings entspricht dem für den Threadbaum, halt nur mit einem Limit von N Postings, zeitlich sortiert. Die Tagcloud sammelt die Tags, die in einer in den Settings festgelegten Periode von jetzt ab zeitlich abwärts benutzt wurden (functions.inc.php, ab Zeile 1633). Das ist, auch abseits der Datenbankabfrage, bestimmt nicht so performant, da diese als Text beim jeweiligen Posting stehen und nach dem Auslesen gesplittet und verarbeitet werden müssen. Die Funktion wird aber z.B. bei Wendell garnicht benutzt. Benutzt du die Tagcloud?

Nichts weist für mich auf die Ursache der langen Wartezeit hin. Falls hier jemand noch eine Idee hat, immer her damit.

Der Effekt tritt weniger zu Tage wenn, wie zur Zeit um 7:00, wenig Betrieb im Forum ist.

Das bestätigt Wendells Beobachtungen. Hier beobachte ich das nur gelegentlich, z.B. nach dem Absenden eines Postings. Das mag am vergleichsweise wenig frequentierten Forum liegen.

Tschö, Auge

--
Trenne niemals Müll, denn er hat nur eine Silbe!


Complete thread:

 RSS Feed of thread