Hallo Mark,
auf die schnelle gesehen, läuft bei invoicelines was falsch. Es wird DISTINCT, GROUP und MIN() gemischt. Entweder das eine oder das andere.. DISTINCT ist teurer als der einfache GROUP BY
bisher:
...
LEFT JOIN ( SELECT DISTINCT ArtName,ItemNrInt,SUM(OrderQty) AS OrderQty,SUM(FullPrice) AS FullPrice,OrderDate,SUM(ItemPriceNoVAT) AS ItemPriceNoVAT,Status
FROM invoicelines WHERE ( OrderQty > '0' AND status = 'AUS' AND invoicelines.attr_department = '6' AND ( invoicelines.OrderDate >= '2012-02-01 00:00:00' AND invoicelines.OrderDate <= '2012-02-09 23:59:59' ))
GROUP BY ItemNrInt
ORDER BY NULL ) invoicelines ON (invoicelines.ItemNrInt = items.ItemNrInt)
...
Vorschlag (siehe MIN(ArtName). Ob das Ergebnis stimmt, mußt Du allerdings prüfen.
...
LEFT JOIN ( SELECT ItemNrInt,MIN(ArtName),SUM(OrderQty) AS OrderQty,SUM(FullPrice) AS FullPrice,OrderDate,SUM(ItemPriceNoVAT) AS ItemPriceNoVAT,Status
FROM invoicelines WHERE ( OrderQty > '0' AND status = 'AUS' AND invoicelines.attr_department = '6' AND ( invoicelines.OrderDate >= '2012-02-01 00:00:00' AND invoicelines.OrderDate <= '2012-02-09 23:59:59' ))
GROUP BY ItemNrInt
ORDER BY NULL ) invoicelines ON (invoicelines.ItemNrInt = items.ItemNrInt)
...
Der EXPLAIN zeigt sehr schön, wie die einzelnen SUB-Select über einen KEY zugreifen können. Die Anzahl der Zeilen in der Spalte "rows" ist jetzt auch im akzeptablen Bereich.
Bei HAVING ist noch etwas Tuning möglich (generell immer auf die korrekten Datentypen achten und kein unnötiges Typescasting erzwingen)
Anstatt
HAVING stockValue > '0'
besser
HAVING stockValue > 0
Zu Deiner Frage: Hier läßt sich aus meiner Sicht nichts machen und hier ist auch nicht das große Performanceproblem würde ich behaupten. Der SUM läßt sich so nicht optimieren ohne alles über den Haufen zu schmeissen.
SUM(IF(invoicelines.OrderQty > 0,invoicelines.OrderQty,0)) AS QtyTotal,
In der Tabelle items_stock ist die Spalte
`locationID` varchar(10) NOT NULL
eventuell auf INT umstellbar (wenn anstatt "All" z. B. dem Wert 0 ersetzt wird und die Abfragen von auf numerische Vergleiche
WHERE items_stock.ItemNrInt = items.ItemNrInt AND (items_stock.locationID = 1 OR items_stock.locationID = 2 )
umgearbeitet werden. Zahlen können einfach schneller verglichen werden als Strings.
Grüße
Thomas