Frage

Was kann ich tun, um diese Abfrage zu optimieren?

SELECT * FROM
    (SELECT `item`.itemID, COUNT(`votes`.itemID)  AS `votes`,
           `item`.title, `item`.itemTypeID, `item`.
           submitDate, `item`.deleted, `item`.ItemCat,
           `item`.counter, `item`.userID, `users`.name,
           TIMESTAMPDIFF(minute,`submitDate`,NOW()) AS 'timeMin' ,
           `myItems`.userID as userIDFav, `myItems`.deleted as myDeleted
      FROM    (votes `votes` RIGHT OUTER JOIN item `item`
                  ON (`votes`.itemID = `item`.itemID))
           INNER JOIN
              users `users`
           ON (`users`.userID = `item`.userID)
    LEFT OUTER JOIN
              myItems `myItems`
           ON (`myItems`.itemID = `item`.itemID)
     WHERE (`item`.deleted = 0)
     GROUP BY `item`.itemID,
              `votes`.itemID,
              `item`.title,
              `item`.itemTypeID,
              `item`.submitDate,
              `item`.deleted,
              `item`.ItemCat,
              `item`.counter,
              `item`.userID,
              `users`.name,
              `myItems`.deleted,
              `myItems`.userID
    ORDER BY `item`.itemID DESC) as myTable
where myTable.userIDFav = 3 or myTable.userIDFav is null
            limit 0, 20 

Ich bin mit MySQL

Danke

War es hilfreich?

Lösung

Natürlich, wie @theomega sagte, Blick auf den Ausführungsplan.

Aber ich würde auch zu versuchen, „aufzuräumen“ Ihre Aussage vor. (Ich weiß nicht, welcher schneller ist -. Die sie auf Ihren Tischgrößen abhängt) Normalerweise würde ich versuchen, mit einer sauberen Aussage zu beginnen und von dort zu optimieren. Aber in der Regel, eine saubere Aussage macht es einfacher für das Optimierungsprogramm mit einem guten Ausführungsplan zu entwickeln.

Also hier sind einige Beobachtungen über Ihre Aussage, die Dinge machen könnte langsam:

  • ein paar Outer-Joins (macht es schwierig für die optimzer einen Index, um herauszufinden, zu verwenden)
  • eine Gruppe von
  • eine Menge von Spalten Gruppe von

Soweit ich Ihre SQL verstehen, diese Aussage sollte die meisten tun, was Ihr tut:

SELECT `item`.itemID, `item`.title, `item`.itemTypeID, `item`.
       submitDate, `item`.deleted, `item`.ItemCat,
       `item`.counter, `item`.userID, `users`.name,
       TIMESTAMPDIFF(minute,`submitDate`,NOW()) AS 'timeMin' 
  FROM    (item `item` INNER JOIN users `users`
       ON (`users`.userID = `item`.userID)

WHERE

Natürlich ist diese vermisst die Informationen aus den Tabellen Sie Außen verbunden, würde ich zu versuchen, Ihnen die gewünschten Spalten über eine subselect hinzuzufügen:

SELECT `item`.itemID, 
       (SELECT count (itemID)
        FROM votes v
       WHERE v.itemID = 'item'.itemID) as 'votes', <etc.>

Auf diese Weise können Sie von einer äußeren loszuwerden beitreten und die Gruppe. Die äußeree Verknüpfung wird durch die subselect ersetzt, so gibt es einen Trade-off, die für die „saubere“ Aussage schlecht sein kann.

Je nach Mächtigkeit zwischen Artikel und MyItems, können Sie das gleiche tun, oder Sie würden mit der Außen bleiben müssen kommen (aber keine Notwendigkeit, die Gruppe wieder einzuführen, durch).

Hope, das hilft.

Andere Tipps

Was bedeutet der Analysator für diese Abfrage sagen? Ohne Wissen darüber, wie viele Zeilen es in der Tabelle ist kippen Sie eine Optimierung sagen. Also den Analysator laufen und Sie werden sehen, welche Teile kostet was.

Einige schnelle semistochastische Gedanken:

Sind Ihre itemID und userID Spalten indiziert?

Was passiert, wenn Sie zu Beginn der Abfrage „Explain“ hinzufügen und es laufen? Gibt es Indizes verwenden? Sind sie sinnvoll?

Sie braucht die ganze innere Abfrage und gefiltert werden, um sie auszuführen, oder könnten Sie setzen den where myTable.userIDFav = 3 or myTable.userIDFav is null Teil in die innere Abfrage bewegen?

Sie scheinen zu viele Felder in der Liste Gruppieren nach zu haben, da einer von ihnen itemID ist, vermute ich, dass Sie eine innere SELECT verwenden könnte die Gruppierung und eine äußere SELECT vorzuformen den Satz von Feldern gewünscht zurückzukehren.

Können Sie nicht hinzufügen, die where-Klausel myTable.userIDFav = 3 oder myTable.userIDFav ist null WHERE (item.deleted = 0) ?

Viele Grüße
Lieven

Schauen Sie sich die Art und Weise Ihre Abfrage erstellt wird. Sie verbinden eine Menge Sachen, begrenzen dann die Ausgabe auf 20 Zeilen. Sie sollten die Außen auf Gegenstände und MyItems beitreten, da nur Ihre Bedingungen für diese beiden Tabellen gelten, beschränken die Ausgabe in den ersten 20 Reihen, dann verbinden und Aggregat. Hier finden Sie eine Menge Arbeit ausführen, die verworfen werden wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top