2016-05-25 13 views
0

Ich benutze MySQL und ich habe eine Tabelle mit über 30 000 Zeilen, die ich später für eine Tabelle auf einer Seite verwenden möchte. Das Problem ist, dass die Abfrage dauert mehr als 1 Sekunde, und ich brauche es beschleunigen, da die Benutzer der Website nur ständig beschweren sich darüber.SQL Query nimmt viel zu lange

Hier ist die Abfrage:

 SELECT `partners`.`id`, 
      `partners`.`first_name`, 
      `partners`.`url`, 
      `partners`.`country`, 
      `partners`.`city`, 
      `partners`.`followers` AS `amount_of_followers`, 
      `partner_user_brand`.`brand_id` AS `brand`, 
      MAX(posts.code_start) AS code_start, 
      MAX(posts.code_end) AS code_end, 
      `partners`.`platforms`, 
      ( SELECT sales 
        FROM posts 
        WHERE partner_id = partners.id 
       ORDER BY posts.code_end DESC 
        LIMIT 1 
      ) AS latest_sale, 
      `partners`.`email`, 
      `partners`.`gender`, 
      `partner_brand_status`.`status_id`, 
      `partners`.`school`, 
      (  SELECT COALESCE(SUM(sales), 0) 
         FROM posts 
        WHERE partner_id = partners.id 
      ) AS tsales, 
      COALESCE(MAX(posts.sales), 0) AS best_sale, 
      IF(partner_user_brand.brand_id=1, RIGHT(contacted, 10), RIGHT(nv_contacted, 10)) AS last_contact 
     FROM `partners` 
    LEFT JOIN `posts` 
     ON `partners`.`id` = `posts`.`partner_id` 
INNER JOIN `partner_user_brand` 
     ON `partners`.`id` = `partner_user_brand`.`partner_id` 
INNER JOIN `partner_brand_status` 
     ON `partners`.`id` = `partner_brand_status`.`partner_id` 
     AND `partner_user_brand`.`brand_id` = `partner_brand_status`.`brand_id` 
    GROUP BY `partners`.`id`, 
      `partner_user_brand`.`brand_id` 

Gibt es eine Möglichkeit, es zu verkürzen oder es schneller zu machen?

Gibt es auch eine schnelle Möglichkeit, die Ergebnisse für die Abfrage zu zählen?

+0

Machen Sie etwas Mühe, um die Abfrage in Ihrer Frage zu formatieren. –

+0

@GordonLinoff Sorry, ich habe Stackoverflow kaum benutzt, um Fragen zu stellen. Werde versuchen. – Ryukish

+0

In diesem Fall sollten Sie folgendes lesen: [ask] – Pred

Antwort

1

Sie können unter Sachen schauen und das kann in der Leistung hilfreich sein:

Ausführungsplan: Untersuchen Sie Ihren Abfrageausführungsplan. Dies wird die besten Ausgangspunkte für die Leistungspunkt For more on execution plan Ansicht sein

Indizes: Sie können die Leistung erhöhen können Indizes für die Säulen, auf denen Sie machen beitritt oder die Spalten in der where Abschnitt durch Zugabe.

Paging: Wie Sie die Daten bereitstellen, ist ebenso wichtig. Benutzer werden keine 3000 Zeilen in einer Aufnahme sehen. So können Sie Paging hinzufügen, um die Leistung zu verbessern

Die Abfrage neu formatieren: Abgesehen von den oben genannten Punkten entfernen Sie die Mehrfachauswahl in der einzelnen Abfrage. Versuchen Sie verbindet Hilfe Dieser kann für diese

0
select 
    a.* 
    ,posts.sales as LatestSale 
from ( 
SELECT `partners`.`id`, 
     `partners`.`first_name`, 
     `partners`.`url`, 
     `partners`.`country`, 
     `partners`.`city`, 
     `partners`.`followers` AS `amount_of_followers`, 
     `partner_user_brand`.`brand_id` AS `brand`, 
     MAX(posts.code_start) AS code_start, 
     MAX(posts.code_end) AS code_end, 
     `partners`.`platforms`, 
     `partners`.`email`, 
     `partners`.`gender`, 
     `partner_brand_status`.`status_id`, 
     `partners`.`school`, 
     SUM(posts.sales) AS tsales, 
     COALESCE(MAX(posts.sales), 0) AS best_sale, 
     IF(partner_user_brand.brand_id=1, RIGHT(contacted, 10), RIGHT(nv_contacted, 10)) AS last_contact 
    FROM `partners` 
LEFT JOIN `posts` 
    ON `partners`.`id` = `posts`.`partner_id` 
INNER JOIN `partner_user_brand` 
    ON `partners`.`id` = `partner_user_brand`.`partner_id` 
INNER JOIN `partner_brand_status` 
    ON `partners`.`id` = `partner_brand_status`.`partner_id` 
    AND `partner_user_brand`.`brand_id` = `partner_brand_status`.`brand_id` 
    GROUP BY `partners`.`id`, 
     `partner_user_brand`.`brand_id`) as a 
left outer join posts 
on a.id = posts.partner_id 
and a.code_end = posts.code_end 

zu verwenden, wie es Sie stoppen Ausführen einer Abfrage letzten Verkauf für jede Zeile zu erhalten, sondern es wird die meisten Ihrer Abfrage verknüpft dann wieder an Pfosten genau das neueste zu bekommen Postwert - auf der id Füge- und die letzten Wert Post code_end bereits für die code_end Säule etabliert

Aber auch Ausführungsplan usw. und sorry überprüfen, wenn Syntax ein wenig von ausgewählten t-sQL ist mein Tag zu Tag

zusammenfassend denken an die logische Ausführung der Anweisung: wenn Sie eine Unterabfrage haben (Wählen Sie den Wert aus ..) vor der FROM in Ihrer Hauptabfrage, dann wird diese Unterabfrage nach Ihrer Hauptabfrage und für jede von Ihrer Hauptabfrage zurückgegebene Zeile ausgeführt. Meine Modifikation wird immer noch die Hauptabfrage ausführen und dann mit der posts-Tabelle verbinden, aber dies wird nur einmal (afaik) für alle Zeilen und nicht nur einmal pro Zeile gemacht. - aber das ist genau das, was ich in diesem Fall standardmäßig tun würde, überprüfen Sie den Ausführungsplan für genaue Informationen