2016-07-25 9 views
1

Haben Sie ein MySQL-Leistungsproblem, das ich nicht bekomme.MySQL Leistungsprobleme für eine einfache Auswahl Abfrage

Diese Abfrage dauert meistens ~ 1 Sekunde zur Ausführung, aber manchmal dauert es 5+ Minuten.

SELECT sb.id AS id, sb.name AS name, 
ROUND(sb.dkprice/100, 0) AS price, bs.name AS shopname, country 
    FROM shopbikes sb, categoriesshopbikes csb, shops s 
    WHERE sb.id = csb.`shopbikeid` 
     AND csb.categoryid = 93 
     AND sb.brand = 'Ghost' 
     AND dkprice > 0 
     AND sb.dkprice IS NOT NULL 
     AND sb.`shopid` = s.id 
    ORDER BY dkprice 
    LIMIT 1 

Es gibt manchmal 5-8 dieser Abfragen, die für verschiedene Marken gleichzeitig ausgeführt werden.

Wenn ich SHOW FULL PROCESSLIST ausführe, kann ich sehen, dass einige dieser Abfragen ausgeführt werden und einige von ihnen seit langer Zeit ausgeführt werden (bis zu mehreren Minuten).

Die Tabellen in der Abfrage haben alle Indizes für alle relevanten Spalten (d. H. Diejenigen, denen die Tabellen entsprechen).

Größe der Tabellen:

  • shopbikes = 600.000 Zeilen
  • categoriesshopbikes = 100.000 Zeilen
  • Geschäfte = 100 Zeilen

Jede Idee, was falsch läuft und wie kann ich fix es?


Update: ich die Abfrage auf eine explizite umgewandelt haben beitreten:

SELECT sb.id AS id, sb.name AS NAME, 
ROUND(sb.dkprice/100, 0) AS price, s.name AS shopname, country 
    FROM shopbikes sb 
    JOIN categoriesshopbikes csb ON (sb.id = csb.shopbikeid) 
    JOIN shops s ON (sb.shopid = s.id) 
    WHERE csb.`categoryid` = 93 
     AND sb.`brand` = 'Cannondale' 
     AND dkprice > 0 
     AND dkprice IS NOT NULL 
    ORDER BY dkprice 
    LIMIT 1 

Es half nicht. Die Ausführung der Abfrage dauert oft lange.


Ausgang Erklären: http://i.imgur.com/kfMPBrd.png

+0

Seitennotiz: Explizite Join-Syntax (auch bekannt als ANSI Join) gibt es seit vielen Jahren (und wahrscheinlich unterstützt MySQL es von Anfang an). Ich schlage vor, Sie versuchen es, da es die Abfrage viel lesbarer macht. –

+0

Bitte posten Sie diese langsamen Abfragen, die in der SHOW FULL PROCESSLIST-Ausgabe aufgelistet sind. –

+0

Wo ist die Ausgabe von 'EXPLAIN'? Von welcher Speichermaschine sprechen wir? Ist Ihr MySQL so abgestimmt, dass Serverressourcen richtig genutzt werden können?Sie müssen die Ausgabe von 'EXPLAIN' bereitstellen (wenn Sie nicht wissen, was es ist, überprüfen Sie ähnliche mysql Fragen), welche Speicher-Engine Sie verwenden, Ausgabe von' SHOW CREATE TABLE' für jede fragliche Tabelle und Ihre MySQL Aufbau. Danach haben wir genug Informationen, um festzustellen, was der Engpass ist und wie man ihn beheben kann. – Mjh

Antwort

1

csb benötigt INDEX(shopbikeid, category_id) in beliebiger Reihenfolge helfen. Wenn categoriesshopbikes eine Viele-zu-viele-Zuordnungstabelle ist, haben Sie alle Empfehlungen here?

sb benötigt INDEX(brand, dkprice), in dieser Reihenfolge.

Ich denke, AND dkprice IS NOT NULL ist redundant mit AND dkprice > 0.

+0

Das Hinzufügen der von Ihnen genannten Indizes scheint das Problem behoben zu haben. – Louisa

+0

Funktioniert jetzt perfekt. Vielen Dank! – Louisa

0
FROM shopbikes sb, categoriesshopbikes csb, shops s 

Ich würde bei der Abfrage-Plan zu sehen, aber ich denke, diese Linie ist das Problem. Diese Art der FROM Klausel wird wahrscheinlich ein kartesisches Produkt aus den aufgelisteten Tabellen erstellen (d.h. 600k * 100k * 100 Zeilen).

Ich vermute, dass die richtige JOIN Klauseln

FROM shopbikes sb JOIN categoriesshopbikes csb ON (sb.id = csb.shopbikeid) JOIN shops s ON (sb.shopid = s.id) 
+0

Danke. Ich habe die Abfrage wie im obigen Update gezeigt bearbeitet. Es hat die Leistung nicht verbessert. – Louisa