Rolf b: langsame MySQL Abfrage

Beitrag lesen

Hallo tobi85,

für das, was Du vorhast, wird der IN schon nötig sein. Der Explain deutet aber an, dass er erstmal den äußeren Select durchführt, was zu einem fetten kartesischen Produkt führt, und es dann auf die im inneren Select gefundenen Artikelnummern reduziert.

Dieses kartesische Produkt musst Du abspecken. Brauchst Du überhaupt den JOIN zur Artikeltabelle? Wenn ich das richtig sehe, wird daraus gar nichts verwendet; die anr steht auch in artikel_attribut.

Dein Subselect sucht in (auftrag_artikel JOIN artikel_attribut) alle Auftragsnummern, in denen ein Artikel mit anr=1 enthalten ist. Der äußere Select macht diesen Join im Prinzip nochmal, sucht darin für die Auftragsnummern alle anr ungleich 1 und zählt, welche anr wie oft vorkommt. Der JOIN mit Artikel erreicht die Zusicherung, dass es zu dieser ANR einen Artikel gibt. Brauchst Du diese Zusicherung?

Den Subselect kannst Du theoretisch auch auf die Ebene des äußeren Select heben; aber ob die Query dadurch schneller wird kann ich nicht sagen. Man kann dadurch aber eine "natürlichere" Reihenfolge angeben:

  • Bilde (auftrag_artikel JOIN artikel_attribut) und reduziere auf ANR='1'
  • Joine alle Aufträge zu diesen Auftragsnummer hinzu
  • Joine alle artikel_attribut mit ANR!='1' hinzu
SELECT COUNT(t2.anr) as count, t2.anr 
FROM artikel_attribut t1 
JOIN auftrag_artikel a1 ON a1.atrnr=t1.atrnr AND t1.anr = '1'
JOIN auftrag_artikel a2 ON a1.auftragnr = a2.auftragnr
                       AND a2.date>'2016-01-04' 
JOIN artikel_attribut t2 ON a2.atrnr = t2.atrnr AND t2.anr != '1'
-- ?? JOIN artikel ON artikel.anr=t2.anr 

GROUP BY t2.anr
ORDER BY count DESC
LIMIT 6

Gruß Rolf