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 ::

TYPO3 Kochbuch

TYPO3 Kochbuch 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)
Hilfe Community Kalender Heutige Beiträge Suchen

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 14.04.2008, 10:28:13
pz6j89 pz6j89 ist offline
Anfänger
 
Registriert seit: Apr 2008
Beiträge: 2
SELECT-Abfrage optimieren

Hallo.

Ich habe die Aufgabe erhalten, die SQL-Anweisungen auf einer stark frequentierten Internetseite zu optimieren. Mein Problem ist eine einzelne SELECT-Abfrage anzupassen. Diese funktioniert bei kleinen Datenmengen (bis 50.000 Datensätze pro involvierte Tabelle) bis auf kleine Performanceprobleme gut. Allerdings haben wir in einer Tabelle von den 5 ca. 600.000 Datensätze. Das Tabellenschema musste ich wegen der Länge des Beitrages als Anhang beifügen.

Die beiden Tabellen "document" und "lng" sind nicht für das Problem verantwortlich und wurden daher von mir nur der Vollständigkeit wegen (ohne Details) angegeben.

Die alte Abfrage versagte. Durch verschiedene Testreihen (entfernen einzelner Bestandteile aus der Abfrage) konnte ich feststellen dass das Problem folgendes ist:

Und zwar muss aus der Tabelle "user" der Benutzername (LoginName) mit Hilfe der in der Tabelle "forumthreadentry" eingetragenen Benutzerid (AuthorId) ausgelsen werden. Dies dauert einfach viel zu lange (bis zu 3 Minuten).

Noch zur weiteren Erklärung: Diese Abfrage zeigt die Übersicht der in einem Topic verfassten Threads an. Diese Threads werden nach der letzten geschriebenen Antwort chronologisch absteigend sortiert. Pro Seite werden 30 Threads angezeigt (dieser Umstand wirkt sich aber nicht auf die Zeit aus. Die Zeit bleibt gleich ob mit oder ohne LIMIT).

Außerdem wäre es schön die ganzen SUBSELECTS aus der Abfrage zu verbannen (sofern möglich).

Hier die alte Abfrage:
Code:
SELECT
  forumthread.Id
  ,forumthread.Locked
  ,forumthread.SolvedState
  ,forumthread.Timestamp
  ,forumthread.Title
  ,forumthread.ViewCount
  ,forumthreadentry.AllowHtml
  ,forumthreadentry.ImageId
  ,forumthreadentry.Text
  ,forumthreadentry.Timestamp
  ,(SELECT
      COUNT(forumthreadentryCount.Id)
    FROM
      forumthreadentry AS forumthreadentryCount
    WHERE
      forumthreadentryCount.ThreadId = forumthread.Id
    LIMIT 1) AS forumthreadentryCount
  ,(SELECT
      COUNT(forumthreadentryCount2.Id)
    FROM
      forumthreadentry AS forumthreadentryCount2
    WHERE
      forumthreadentryCount2.AuthorId = @userId
    AND
      forumthreadentryCount2.ThreadId = forumthread.Id
   ) AS forumthreadentryCount2
  ,forumthreadentryUser.Id
  ,forumthreadentryUser.LoginName
  ,forumthreadUser.Id
  ,forumthreadUser.LoginName
  ,forumthread.LngId AS LngId
  ,flagDocument.Id AS LngFlagId
  ,flagDocument.Extension AS LngFlagExtension
  ,forumthreadentrylast.Timestamp AS LastEntryTimeStamp

FROM
  forumthread

LEFT JOIN
  forumthreadentry AS forumthreadentrylast
ON
  forumthreadentrylast.Id = (SELECT
                               forumthreadentryUserSelect.Id
                             FROM
                               forumthreadentry AS forumthreadentryUserSelect
                             WHERE
                               forumthreadentryUserSelect.ThreadId = forumthread.Id
                             ORDER BY
                               forumthreadentryUserSelect.Timestamp DESC
                             LIMIT 1)

LEFT JOIN
  forumthreadentry
ON
  forumthreadentry.ThreadId = forumthread.Id

LEFT JOIN
  user AS forumthreadentryUser
ON
  forumthreadentryUser.Id = forumthreadentrylast.AuthorId

JOIN
  user AS forumthreadUser
ON
  forumthreadUser.Id = forumthread.AuthorId

LEFT JOIN
  lng AS forumthreadLng
ON
  forumthreadLng.Id = forumthread.LngId

LEFT JOIN
  document AS flagDocument
ON flagDocument.Id = forumthreadLng.SmallFlagImage

WHERE
  forumthread.TopicId = @forumTopicId

GROUP BY
  forumthread.Id

ORDER BY
  forumthreadentrylast.Timestamp DESC
  ,forumthread.Timestamp DESC

LIMIT
  0
  ,30;
Und hier meine derzeit aktuellste Abfrage:
Code:
SELECT
  forumthread.Id
  ,forumthread.Title
  ,forumthread.Locked
  ,forumthread.SolvedState
  ,forumthread.Timestamp AS Open_Timestamp
  ,MAX(forumthreadentry.Timestamp) AS LastPost_Timestamp
  ,forumthreadentry.AuthorId
  ,user.LoginName
  ,forumthread.ViewCount
  ,f_countthreads(forumthreadentry.ThreadId) AS counter2
  ,forumthreadentry.AllowHtml
  ,forumthreadentry.ImageId
  ,forumthread.LngId AS LngId
  ,document.Id AS LngFlagId
  ,document.Extension AS LngFlagExtension
FROM
  forumthreadentry

LEFT JOIN
  forumthread
ON
  forumthread.Id = forumthreadentry.ThreadId

LEFT JOIN
  user
ON
  user.Id = forumthreadentry.AuthorId

LEFT JOIN
  lng
ON
  lng.Id = forumthread.LngId

LEFT JOIN
  document
ON
  document.Id = lng.SmallFlagImage

WHERE
  forumthread.TopicId = @forumTopicId
GROUP BY
  forumthreadentry.ThreadId

ORDER BY
  LastPost_Timestamp DESC

LIMIT
  0
  ,30;
Dazu gehört auch die folgende Funktion:
Code:
DELIMITER $$

DROP FUNCTION IF EXISTS `f_countthreads` $$
CREATE DEFINER=`root`@`localhost` FUNCTION `f_countthreads`(ThreadId INT) RETURNS int(11)
BEGIN
  DECLARE counter INT;
  SELECT
           COUNT(forumthreadentry.ThreadId) INTO counter
         FROM
           forumthreadentry
         WHERE
           forumthreadentry.ThreadId = ThreadId
         LIMIT 1;
  RETURN counter;
END $$

DELIMITER
Ich hoffe das ich genügend Informationen zur Verfügung gestellt habe und das ihr mir helfen könnt.

Gruß Oli
Angehängte Dateien
Dateityp: txt tabellenschema.txt (5,0 KB, 95x aufgerufen)
Mit Zitat antworten
  #2  
Alt 14.04.2008, 12:04:28
Benutzerbild von |Coding
|Coding |Coding ist offline
Administrator
 
Registriert seit: Apr 2002
Ort: Bergheim
Alter: 41
Beiträge: 5.255
|Coding eine Nachricht über Skype™ schicken
AW: SELECT-Abfrage optimieren

Hi!

Du könntest mal nachsehen, ob Du vielleicht noch Indizes hinzufügen kannst.

Nutze dazu: EXPLAIN Dein_SQL_Statement
__________________
Gruß |Coding

---
Qozido® - Die Bilderverwaltung mit Logbuch für Taucher und Schnorchler.

www.qozido.de
Mit Zitat antworten
  #3  
Alt 14.04.2008, 12:10:19
pz6j89 pz6j89 ist offline
Anfänger
 
Registriert seit: Apr 2008
Beiträge: 2
AW: SELECT-Abfrage optimieren

Ich habe das jetzt mal ausgeführt und den Screenshot hier mal angehängt. Also ich glaube das ich keine zusätzlichen Indizies mehr benötige.
Miniaturansicht angehängter Grafiken
abfrage_explain.jpg  

Geändert von pz6j89 (15.04.2008 um 08:58:45 Uhr) Grund: Änderung des Screenshots
Mit Zitat antworten
Antwort


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

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
SELECT Abfrage nur mit gefüllten Werten Skyman MySQLi/PDO/(MySQL) 0 24.10.2007 23:01:50
Select Abfrage? so richtig?! Soeren MySQLi/PDO/(MySQL) 1 11.07.2004 10:52:28
Select Abfrage für 2 Tabellen muc PHP für Fortgeschrittene und Experten 2 16.08.2003 13:33:25
Knifflige SELECT Abfrage alaska MySQLi/PDO/(MySQL) 7 12.08.2003 17:12:13
select feld mit if abfrage? Silencer PHP für Fortgeschrittene und Experten 3 20.11.2002 09:34:59


Alle Zeitangaben in WEZ +2. Es ist jetzt 08:23:31 Uhr.


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


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