![]() |
| | Themen-Optionen |
| | Nach oben #1 |
| Christian Mühlroth Registriert seit: 04.09.2005 Ort: Nürnberg
Beiträge: 561
|
Tag, nun ich bin an einem Punkt, andem mein Projekt langsam an programmiertechnischer Größe gewinnt. Hierbei bin ich nun auf ein Problem gestoßen, welches von recht großer Bedeutung ist: die Performance. Dabei geht es um meine Template-Klasse und um die Sprachvariablen. Kurze Erklärung: Ich speichere meine Sprachvariablen (auch ganze Phrasen) in der Datenbank. Ich habe mich für die Datenbank entschieden, da ich diese Lösung dynamischer und für den Admin der Software leichter zu verwalten finde. Ich hab das so gelöst, dass ich die TemplateEngine (Methode: replaceLanguageVariables()) die Sprachvariablen per regex raussucht (gekennzeichnet mit {§sprachVariable§}), und die nötigen Felder dann aus der Datenbank holt. Das hat am Anfang auch perfekt und schnell geklappt, hatte hier ja schonmal eine Frage dazu gestellt. Nun habe ich aber festgestellt, dass der Aufbau meiner Seiten ca. 0.1 Sekunden braucht - ist zwar immer noch schnell, für mich aber noch nicht schnell genug. Vorallem wenn das System noch wächst, und noch mehr hinzukommt. Doch dann habe ich angefanen, Templates zu verschachteln (z.b. HTML Kopf und Fuß), und auch einige Grundrahmen innerhalb der Tempaltes zu includen, damit nicht so viel an den Templates zu verändern ist, sondern einfach nur der neue COntent generiert werden muss - das ist ja auch der Sinn von Tempaltes. Doch bei jedem neu includierten Template müssen ja auch die dortigen Sprachvariablen gesucht und ersetzt werden - und so häufen sich die Querys leider nach und nach. Dann gibt es noch das Problem, dass ich beispielsweise mal eine einzelne Sprachvariable brauch (Methode getLanguageVariable()), was dann natürlich wieder einen einzelnen Query erfordert, sodass ich zurzeit auf maximal 15 Querys / Seite komme, bei einer Laufzeit von ~0.1 - 0.13 Sekunden. Das sieht wie folgt aus: Code:
// SessionDaten auslesen
SELECT sessionData FROM xpc1_sessions WHERE sessionID = 'd356ca7d1853009a9b51609d2da598a7' AND expireDate >= '1156623419'
// Aufgrund von session_regenerate_id() wird die alte SessionID gelöscht
DELETE FROM xpc1_sessions WHERE sessionID = 'd356ca7d1853009a9b51609d2da598a7'
// Hier werden die MainSettings geladen
SELECT c.styleID, c.chattitle, c.gzCompression, s.name, s.path, s.templatepath, s.imagepath, s.cachepath, s.csspath, s.jspath, s.fileextension, l.langname, l.langidentifier FROM xpc1_config AS c INNER JOIN xpc1_styles AS s ON s.id = c.styleID INNER JOIN xpc1_languages AS l ON l.id = c.languageID
// Auslesen der UserDaten des eingeloggten Users
SELECT id, username, usergroup, status FROM xpc1_users WHERE id = '1'
// Query für den StatusSelector (online, abwesend, unsichtbar etc..)
SELECT id, statusIdentifier FROM xpc1_status
// Dieser Query ist für die Anzeige "Wer ist Online"
SELECT u.id AS userID, u.username, c.id AS roomID, c.roomname FROM xpc1_users AS u LEFT JOIN xpc1_chatrooms AS c ON u.chatroom = c.id WHERE u.chatroom != '0' AND u.isOnline = '1'
// Ab hier - Languagevariablen..
// Raumübersicht
SELECT phraseContent, identifier FROM xpc1_language_de WHERE identifier IN ('roomOnline')
// Raumübersicht -> keine User online
SELECT phraseContent, identifier FROM xpc1_language_de WHERE identifier IN ('noUserOnline')
// Einzelne Variablen für die Breadcumb-Navigation
SELECT phraseContent FROM xpc1_language_de WHERE identifier = 'userControlCenter'
SELECT phraseContent FROM xpc1_language_de WHERE identifier = 'manageFriendlist'
SELECT phraseContent FROM xpc1_language_de WHERE identifier = 'deleteUser'
// Verschachtelte Templates
SELECT phraseContent, identifier FROM xpc1_language_de WHERE identifier IN ('usercontrolcenterWelcometext')
SELECT phraseContent, identifier FROM xpc1_language_de WHERE identifier IN ('youAreHere','yourStatus','friendsOnlineNum','xNewPMs','oneNewPM','noNewPMs')
SELECT phraseContent, identifier FROM xpc1_language_de WHERE identifier IN ('manageFriendlistWelcome','addUser','addUser')
SELECT phraseContent, identifier FROM xpc1_language_de WHERE identifier IN ('online','busy','rightback','away','longeraway','invisible')
Vielleicht hat von euch einer eine Idee, wie ich das System optimieren kann, sodass ich vllt weniger Querys brauche? Leider habe ich da keine passende Idee dazu gehabt, somit poste ich die Frage einfach mal hier. Hoffe auf gute Ideen
__________________ http://www.ChrisDiary.De Geändert von Chr!s (26.08.2006 um 22:36 Uhr). |
| | |
| | Nach oben #2 |
| leftover when bar closes Registriert seit: 29.06.2006 Ort: Bern
Beiträge: 123
|
Hmm, was ich auf die Schnelle gerade sehe: die Userdaten könntest du nach erfolgreichem Login doch direkt in die Session legen. Bei deinem Sessionhandler passiert ohnehin bereits eine Querie vor und eine nach der Ausführung des Scripts ("unsichtbar"). Das ginge also gleich in einem Zug. Wobei diese eine Querie natürlich noch keinen grossen Unterschied machen wird. Das Problem liegt klar bei deinen Sprach-Abfragen. Wie wäre es, wenn du Spracheinträge geschickt gruppierst und die ganze Gruppe mit einer einzigen Query ausliest? (serialize(), unserialze()) Zb sämtliche Sprach"dateien" für Menüelemente wie Kopieren, Löschen, Editieren, Verschieben, Erstellen uswusw... All diese Elemente könntest du serialisieren und im Feld "usrControls" speichern... Auslesen, unserialize und du hast ein praktisches assoziatives Array mit den Daten. Das ganze setzt natürlich ein geschicktes System voraus, die Elemente müssten logisch gruppiert werden.
__________________ Unkraut ist die Opposition der Natur gegen die Regierung der Gärtner. ticketbörse |
| | |
| | Nach oben #3 | ||
| Christian Mühlroth Registriert seit: 04.09.2005 Ort: Nürnberg
Beiträge: 561
| Zitat:
Zitat:
Einziges Problem dabei: Standard-Wörter wie "fortfahren" "username", "Passwort" oder "Okay" (nur Beispiele, vielleicht nicht gerate die besten) müssen dennoch geladen werden. Aber ich werde mir mal Gedanken über deinen Vorschlag machen. Falls noch andere Ideen existieren - nur her damit //edit Ohje, derzeit ist es sogar schneller alle Sprachvariablen zu lesen und in den kleinen internen Cache (einfach ein Array) meinem View zu packen. (Es wird immer geprüft, ob die Variable nicht schomal geholt wurde, wenn doch wird auf diesen "Cache" zugegriffen). Das ändert sich aber denke ich, wenn noch mehr Sprachvariablen dazukommen (und da kommen noch einige)..
__________________ http://www.ChrisDiary.De Geändert von Chr!s (27.08.2006 um 01:24 Uhr). | ||
| | |
| | Nach oben #4 |
| Benjamin Steininger Registriert seit: 02.06.2005 Ort: weiher im tiefsten Odenwald
Beiträge: 1.180
|
eine eventuell etwas umständlicher weg wäre der templateklasse beizubringen, die übersetzungen erst wenn das letzte template erkannt ist aus der datenbank zu holen, damit beugst du auch dem vor, dass du eventuell felder doppelt abholst und sobald du mit einem query alle relevanten daten abgeholt hast, dann erst werden die templates geparst, das kombiniert mit nem templates-cache vieleicht ? mfg robo47 |
| | |
| | Nach oben #5 | |
| leftover when bar closes Registriert seit: 29.06.2006 Ort: Bern
Beiträge: 123
| Zitat:
Ansonsten klingt robo's Vorschlag sehr gut, bleibt die Schwierigkeit, ein funktionelles caching für die Templates hinzukriegen. Davon hab' ich sehr wenig Ahnung, es schien mir jedoch verdammt knifflig bei meinen wenigen rein interessehalber angestekkten Testläufen.
__________________ Unkraut ist die Opposition der Natur gegen die Regierung der Gärtner. ticketbörse | |
| | |
| | Nach oben #6 | ||
| Christian Mühlroth Registriert seit: 04.09.2005 Ort: Nürnberg
Beiträge: 561
| Zitat:
Das müsste ich mal ausprobieren, mein erster Gedanke wäre jetzt jedoch, dass mir dann entweder mein internes Array zu groß wird oder dass das dann an meiner verschachtelung der Templates hängenbleibt - ich werde es aber mal probieren. Zitat:
__________________ http://www.ChrisDiary.De | ||
| | |
| | Nach oben #7 |
| Gast
Beiträge: n/a
|
naja, ein plausibler weg, um "ripple loading" zu verhindern und trotzdem "lazy loading" zu implementieren: * du speicherst auf jeden fall alle 'einmal geladenen' language-keys in einem array. den selben key zweimal aus der datenbank zu holen, wäre ja nicht sinnvoll. * wenn du einen language-key nicht im 'cache' finden kannst, lädst du nicht nur den wert, sondern die ganze gruppe, die diesen wert enthält, denn du wirst wahrscheinlich bald auch einen anderen wert aus dieser gruppe benötigen. d.h. deine statements werden: Code: SELECT * FROM lang WHERE packet IN ( SELECT lang_b.packet FROM lang lang_b WHERE lang_b.lang_key IN (a, b) ) ... du musst dann halt ganz genau schauen, dass du keine werte doppelt holst (doppelte gruppen-zugehörigkeit), und wann es passieren kann, dass du doch die komplette tabelle gezogen hast. Geändert von axo (27.08.2006 um 11:22 Uhr). |
|
| | Nach oben #8 |
| Martin Breuer Registriert seit: 17.08.2005 Ort: Berlin
Beiträge: 1.642
|
Robos idee ist definitiv wert, getestet zu werden. Ähnlich wäre es einfach, gewisse Phrasen zu Gruppieren und dann mit einem Query diese Gruppe auszulesen. Du müsstest also nur ne Gruppentabelle erstellen und jeder "Seite" eine Gruppe zuweisen. Und dann halt Gruppenweise auslesen und speichern.
__________________ I did it my way - Senseless-Blog |
| | |
| | Nach oben #9 | |
| Christian Mühlroth Registriert seit: 04.09.2005 Ort: Nürnberg
Beiträge: 561
| Zitat:
__________________ http://www.ChrisDiary.De Geändert von Chr!s (27.08.2006 um 12:49 Uhr). | |
| | |
| | Nach oben #10 |
| leftover when bar closes Registriert seit: 29.06.2006 Ort: Bern
Beiträge: 123
|
Lol entweder ralle ich die Posts der anderen nicht ganz oder jeder hier schlägt ein wenig dasselbe vor, ein wenig anders formuliert - wir drehen uns im Kreis...
__________________ Unkraut ist die Opposition der Natur gegen die Regierung der Gärtner. ticketbörse |
| | |
| | Nach oben #11 | |
| Christian Mühlroth Registriert seit: 04.09.2005 Ort: Nürnberg
Beiträge: 561
| Zitat:
2 konkrete Vorschläge habe ich jetzt bekommen, die ich auch austesten werde: * Templates kurz intern cachen und Sprachvariablen erst am Ende ersetzen * Sprachvariablen logisch gruppieren und auch gruppiert auslesen
__________________ http://www.ChrisDiary.De | |
| | |
| | Nach oben #12 |
| leftover when bar closes Registriert seit: 29.06.2006 Ort: Bern
Beiträge: 123
|
3. Die Möglichkeit der Kombination beider Varianten
__________________ Unkraut ist die Opposition der Natur gegen die Regierung der Gärtner. ticketbörse |
| | |
| | Nach oben #13 |
| Martin Breuer Registriert seit: 17.08.2005 Ort: Berlin
Beiträge: 1.642
|
Mein Post ist dem von axo recht ähnlich. ich sollte demnächst gründlicher querlesen, das stimmt.
__________________ I did it my way - Senseless-Blog |
| | |
| | Nach oben #14 |
| Christian Mühlroth Registriert seit: 04.09.2005 Ort: Nürnberg
Beiträge: 561
|
Robos Idee war die einleuchtende für mich, so hab ich mich von 16 Querys auf 7 Querys runterschrauben können, das is denk ich doch eine ganz schöne Leistung. Das Gruppieren von Sprachvariablen fällt mir derzeit noch etwas schwer (die logische Eintelung, das müsste ich noch etwas ausbauen), aber da ich derzeit eh nur einen Query für alle Sprachvariablen benötige, ist eine gruppierung für diesen Zweck eher unnötig. Danke
__________________ http://www.ChrisDiary.De |
| | |
![]() |
| Lesezeichen |
| Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1) | |
| Themen-Optionen | |
| |
Ähnliche Themen | ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| Problem mit meiner mysql class | Stefan125 | PHP-Programmierung | 13 | 20.09.2007 22:45 |
| [Xampp 1.6.2] Mysql kann nicht geladen werden, oder doch?! | kampfgnom | Tools, Server, Betriebssysteme | 10 | 14.07.2007 13:58 |
| MySQL 5.1 kommt in die Beta-Phase | Ben | Nachrichten | 1 | 02.03.2006 14:31 |
| Problem mit Tutorial: Login mit Sessions und MySQL | Jan | PHP-Programmierung | 10 | 08.01.2006 19:58 |
| Problem bei Verwendung von IF bei MySQL | Ben | Datenbanken | 2 | 22.12.2005 16:00 |