SELFPHP: Version 5.8.2 Befehlsreferenz - Tutorial – Kochbuch – Forum für PHP Einsteiger und professionelle Entwickler

SELFPHP


Professional CronJob-Service

Suche



CronJob-Service    
bei SELFPHP mit ...



 + minütlichen Aufrufen
 + eigenem Crontab Eintrag
 + unbegrenzten CronJobs
 + Statistiken
 + Beispielaufrufen
 + Control-Bereich

Führen Sie mit den CronJobs von SELFPHP zeitgesteuert Programme auf Ihrem Server aus. Weitere Infos



:: Buchempfehlung ::

Fortgeschrittene CSS-Techniken

Fortgeschrittene CSS-Techniken zur Buchempfehlung
 

:: Anbieterverzeichnis ::

Globale Branchen

Informieren Sie sich über ausgewählte Unternehmen im Anbieterverzeichnis von SELFPHP  

 

:: Newsletter ::

Abonnieren Sie hier den kostenlosen SELFPHP Newsletter!

Vorname: 
Name:
E-Mail:
 
 

Zurück   PHP Forum > SELFPHP > MySQLi/PDO/(MySQL)

MySQLi/PDO/(MySQL) Anfänger, Fortgeschrittene oder Experten können hier Fragen und Probleme rund um MySQLi/PDO/(MySQL) diskutieren

Antwort
 
Themen-Optionen Ansicht
  #1  
Alt 17.06.2011, 12:54:28
Balael Balael ist offline
Anfänger
 
Registriert seit: Jun 2011
Alter: 58
Beiträge: 2
Hilfe beim Tunen von MySQL Statements erbeten

Guten Morgen,

ich habe ein Skript für die Verwaltung von Aufgaben erstellt mit einfachen Mitteln, da ich MySQL & PHP gerade im Anfangsstadium beherrsche. Das Skript läuft auch soweit. Aufgrund der regen Benutzung zeigen sich jetzt langsam Performance Probleme, da die Datenbank wächst und die Abfragen aufwändig werden (nicht von der Logik, sondern von der Menge der Datensätze). Da MySQL aber mit der Anzahl in meiner DB kein Problem haben sollte (z.B. 15.000 Einträge) gehe ich mal davon aus, daß meine Statements nicht gut sind. Ich habe mal SlowQuery laufen lassen und einige Statements gefunden, die die Ursache zu sein scheinen, teilweise mit Laufzeiten von > 70 Sekunden. Der Blick zeigt über 87000000 bearbeitete Datensätze - das klingt so, als ob ich mit meinem Statements eine Unmenge von unnötigen temporären Daten erzeuge und daher die Ausführung sehr langsam wird.

Ich würde mich sehr freuen, wenn mir jemand einen Tipp geben kann, in welche Richtung ich meine SQL-Statements verbessern kann.

Ich habe hier mal zwei Beispiele von Statements, die Sorgen machen. Mit Euren Tipps kann ich dann ähnliche Statements sicher auch anpassen.

Beispiel 1:

Ich suche eine Aufgaben, die bestimmte Kriterien erfüllen müssen. Dazu lasse ich mir die gewünschten Infos raussuchen und verknüpfe per JOIN mit einigen anderen Tabellen, um die nötigen Infos für den Benutzer herauszubekommen. Um doppelte Ausgaben zu vermeiden, habe ich versucht mit Hilfe der GROUP BY und der DISTINCT Anweisung dafür zu sorgen, daß nur jeweils ein Datensatz pro ID ausgegeben wird.

Tabellen:
aufgaben = Alle Aufgaben im System (preFix hau_)
aufgaben_mitarbeiter = Zuweisung von Aufgaben an Mitarbeiter (preFix uau_)
mitarbeiter = Mitarbeiterdaten (Prefix hma_)
typ = Aufgabentyp (Prefix uty_)
aufgaben_zuordnung = Gruppenzuweisung (Prefix uaz_)
level = Rechtetabelle (Prefix ule_)
projekte = Projekte (Prefix hpr_)
prioritaet = Aufgabenprio (Prefix upr_)

SELECT DISTINCT uau_hauid,
hau_hprid,
hau_prio,
hau_id,
hau_ticketnr,
upr_name,
hau_titel,
hau_beschreibung,
hau_datumstyp,
hau_anlage,
hau_pende,
hma_login,
hau_abschluss,
hpr_titel,
ule_name,
uty_name
FROM aufgaben
LEFT JOIN aufgaben_mitarbeiter ON hau_id = uau_hauid
LEFT JOIN mitarbeiter ON hau_inhaber = hma_id
LEFT JOIN typ ON hau_typ = uty_id
LEFT join aufgaben_zuordnung ON hau_id = uaz_hauid
LEFT JOIN level ON uaz_pg = ule_id
LEFT JOIN projekte ON hau_hprid = hpr_id
LEFT JOIN prioritaet ON hau_prio = upr_nummer
WHERE hau_abschluss = 1
AND hau_aktiv = 1 GROUP BY hau_id
ORDER BY hau_anlage DESC LIMIT 150;

Es gibt sicher einen besseren Weg um aus der Datenbank die gewünschten Daten ohne Dubletten von hau_id zu bekommen?

2. Beispiel mit einer anderen Aufgabe):

Wunschausgabe wären die Aufgaben, die zwei Bedingungen erfüllen. So sollen alle Aufgaben gefunden werden, die von einem Mitarbeiter übernommen wurden aber noch unbearbeitet sind (erstes Subselect) oder für die ein anderer Bearbeiter einen PING (=Benachrichtigung) eingestellt hat, aber der Bearbeiter nicht zwangsläufig auch der Aufgabe zugeordnet ist. Die beiden Subselects waren mein Ansatz, um beide Arten zu erwischen, da ich über verschiedene Bedingungen suchen muss. In diesem Falle ist mit der AND Sequenz nach den Subselects noch ein Filter auf die Gruppe gelegt und den Aufgabentyp:

SELECT *, m1.hma_login AS inhaber, m2.hma_login AS mitarbeiter, m3.hma_login AS teamleiter

FROM aufgaben
LEFT JOIN aufgaben_mitarbeiter ON hau_id = uau_hauid
LEFT JOIN mitarbeiter m1 ON hau_inhaber = m1.hma_id
LEFT JOIN mitarbeiter m2 ON uau_hmaid = m2.hma_id
LEFT JOIN mitarbeiter m3 ON hau_teamleiter = m3.hma_id
LEFT JOIN typ ON hau_typ = uty_id LEFT
JOIN aufgaben_zuordnung ON uaz_hauid = hau_id
LEFT JOIN level ON uaz_pg = ule_id LEFT JOIN projekte ON hau_hprid = hpr_id
INNER JOIN prioritaet ON hau_prio = upr_nummer WHERE

hau_id IN(
SELECT DISTINCT hau_id FROM aufgaben
LEFT JOIN aufgaben_mitarbeiter ON hau_id=uau_hauid
WHERE (uau_hmaid = "73" AND hau_aktiv = "1"
AND uau_status = 0 AND uau_ma_status = 1
)
OR
hau_id IN(
SELECT DISTINCT hau_id FROM aufgaben
LEFT JOIN log ON ulo_aufgabe = hau_id
LEFT JOIN log_status ON uls_uloid = ulo_id
WHERE hau_aktiv = "1" AND hau_abschluss = 0
AND uls_ping_an = 73
)
AND uaz_pg=4 AND hau_typ=16
GROUP BY hau_id
ORDER BY hau_zeitstempel DESC;

Das Konstrukt ist sicher nicht das "How-todo-it" - habt Ihr eine Anregung, wie man eine solche Frage anders abbildet?

Sehr geholfen wäre mir auch schon mit einer Idee, wie ich die GROUB BY hau_id (also den Ansatz, doppelte Datensätze mit der gleichen Aufgaben-ID zu vermeiden) ersetzen kann - ich denke, sie ist ein grund für die hohe Menge an temporären Datensätzen. Ich denke, die GROUPY BY ist vom Gefühl her zu mächtig für diese Aufgabe und es gibt ggf. eine sinnvolle Syntax, um in der Abfrage Dubletten auszuschließen?

Für jeden Input oder Hinweis sehr dankbar,
Balael
Mit Zitat antworten
  #2  
Alt 22.06.2011, 01:57:33
rei rei ist offline
Anfänger
 
Registriert seit: Sep 2010
Ort: Sünching bei Straubing - Regenburg
Alter: 51
Beiträge: 17
AW: Hilfe beim Tunen von MySQL Statements erbeten

Naja,...

vielleicht hilft folgendes:

allgemein:
-Die Felder die Du vergleichst in JOIN und WHERE müssen vom EXAKT gleichen Typ sein,
RICHTIG: tab1.id (integer10) = tab2.id (integer10)
FALSCH: tab1.id (integer10) = tab2.id (integer12)

Auch fraglich: ...WHERE hau_aktiv = "1" ...
Ist das wirklich ein STRING oder ein INTEGER?
Sonst macht MySQL eine Typenwandlung und das dauert.

-Da bei beiden Beispieln die releventen Felder (Ausgabe von Select und Where)
ja NICHT NULL sind, kannst Du auch immer INNER JOIN verwenden;
dann wird die 'temporäre Kreuztabelle' schon mal kleiner.

-Bezüglich Indizies geh ich mal davon aus, daß die passen ;)
(Da hab ich bei alten Beiträgen ein paar Links angebracht)

Zu Beispiel 1.):
-Bei den JOINS erst die Tabellen mit den geringsten Einträgen 'einbinden' und hinten raus die grossen Tabellen (Anzahl der Einträge).
Der GROUP BY und DISTINCT erscheint mir 'doppelt gemoppelt'.
DISTINCT sollte schneller gehen als der GROUP BY (denn also raus.)

Anderer Ansatz:
Die ganzen JOINs machst Du ja anscheinend,
um Deinen SELECT/WHERE auf Tabelle 'hau_'
mit eine paar Zusatzinfos zu erweiteren (Real-Name von Personen ala 'Mach aus der id einen lesbaren Namen.'...)
Eigentlich willst Du ja nur 150 Einträge mit einer einfachen WHERE-Klausel.
Nun der andere Ansatz:
Bau dir die JOINs doch in PHP nach.
-1.Mach doch den SELECt/WHERE OHNE die ganzen Joins.
-2.Lies die in PHP(Result-array von -1. ) die IDs der anderen Tabellen aus.
-3.SELECT die anderen 'Unter'-Tabellen in einem zweiten,.. Schritt.
-4.foreach-Schleife durch Dein Result-array von -1. und 'gibt' die Ergebnisse aus -3. dazu.

Aus einem SELECT mit Millionen von (temporären) Möglichkeiten,
machst Du drei, vier SELECTs mit jeweils unter 150 Ergebnissen.
Dieser zweite Ansatz ist NICHT elegant, aber für MySQL SEHR speicherschonend,
die Verbindungszeit zu Db ist ja aus gering und PHP schafft die paar array-'Gegenüberstellungen' auch schnell. Vielleicht baust Du Dir ja eine array-callback Funktion ;)

Zum Beispiel 2.:
Wegen den ...,
m1.hma_login AS inhaber,
m2.hma_login AS mitarbeiter,
m3.hma_login AS teamleiter ...-Werten
und deren JOINs gilt das gleiche wie bei Beispiel 1.
=> Erst mal ohne die RealNamen-Selecten, bzw einen SlowQuery laufen lassen
u.U. mit PHP die Namen nachziehen.

-folgende JOINs sind (glaub ich) unnütz:
'...LEFT JOIN typ ON hau_typ = uty_id...'
'...LEFT JOIN projekte ON hau_hprid = hpr_id...'
'...LEFT JOIN aufgaben_zuordnung ON uaz_hauid = hau_id ...'
Siehst so aus, als hast Du einen anderen SELECT kopiert und 'umgebaut'.

Der 'SELECT *' bzw. SELECT aufgaben.*
zieht ja auch vile Felder mit, die Du wohl nie brauchen wirst bei der Verarbeitung in PHP,
aber die tempTable von MySQL aufbläst.

Auf die Subselect geh ich nicht ein, da will ich mich nicht aus dem Fenster lehnen.
Ein DISTINCT anstatt des GROUP BY vom Ende könnte vielleicht auch was helfen.
Einfach mal testen.
__________________
Meine Tochter: kleine Frau ganz gross

Reinhard Neidl Webprogrammierung
Mit Zitat antworten
  #3  
Alt 26.06.2011, 20:25:18
Balael Balael ist offline
Anfänger
 
Registriert seit: Jun 2011
Alter: 58
Beiträge: 2
AW: Hilfe beim Tunen von MySQL Statements erbeten

Hallo,

vielen Dank für die große Menge Input - die muss ich erstmal verdauen :)

Glücklicherweise lacht ab Dienstag der Urlaub - und ich neige dazu, den sonnigen Strand dem Laptop vorzuziehen (shame on me). Beim Durchlesen habe ich aber schon sehr viel Hilfreiches gefunden, z.B. die "" - da habe ich bisher kein Auge drauf gehabt. Die fliegen bei Integer schon mal raus.

Auch der Gedanke, die Statements zu verkleinern und die Logik in den Code zu legen - spannend, wäre auf jeden Fall eine Option.

Auf jeden Fall ein dickes Danke für die investierte Zeit. Sobald ich zurück bin, werde ich das ausprobieren und hier berichten.

Grüße von
B
Mit Zitat antworten
Antwort


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind aus.
[IMG] Code ist aus.
HTML-Code ist aus.

Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Brauche Hilfe Partygirl MySQLi/PDO/(MySQL) 10 01.03.2011 09:18:11
Hilfe Fehlercode #1064 MySql Daru89 MySQLi/PDO/(MySQL) 3 16.02.2009 16:39:43
Brauche Hilfe: Vererbung in einer relationalen Datenbank (mySQL) derFuxx MySQLi/PDO/(MySQL) 0 09.02.2008 01:37:26
Hilfe für MYSQL hbriele MySQLi/PDO/(MySQL) 3 26.08.2006 19:22:31
Hi, Brauche Hilfe bei config von MySql xDragonx MySQLi/PDO/(MySQL) 2 18.11.2004 09:57:36


Alle Zeitangaben in WEZ +2. Es ist jetzt 09:51:59 Uhr.


Powered by vBulletin® Version 3.8.3 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.


© 2001-2024 E-Mail SELFPHP OHG, info@selfphp.deImpressumKontakt