I have a performance issue with one of my queries.
The slow query:
SELECT
Stock.StockID,
Stock.sku AS SKU,
Stock.ProductName AS PRODUCT,
SUM(OrderItems.[quantity-purchased]) AS Qty
FROM
Orders, OrderItems, CMRC_Stock as Stock
WHERE
Orders.[status] = 'PRINTED' AND
Orders.[order-id] = OrderItems.[order-id] AND
(Stock.SKU = OrderItems.SKU OR
OrderItems.sku IN (SELECT SKU FROM AlternateSKUS WHERE StockID = Stock.StockID) OR
Stock.BarCode = OrderItems.SKU) AND
Orders.channelId != 21
GROUP BY Stock.StockID, Stock.sku, Stock.ProductName
ORDER BY Qty DESC, Stock.sku
This takes around 11 seconds to return the result.
I tried to optimise the query, removing the nested SELECT from the WHERE clause and came up with this:
SELECT
Stock.StockID,
Stock.sku AS SKU,
Stock.ProductName AS PRODUCT,
SUM(OrderItems.[quantity-purchased]) AS Qty
FROM
Orders
FULL OUTER JOIN OrderItems ON Orders.[order-id] = OrderItems.[order-id]
LEFT OUTER JOIN CMRC_Stock as Stock ON OrderItems.sku = Stock.SKU
LEFT OUTER JOIN AlternateSKUS ON AlternateSKUS.StockID = Stock.StockID
WHERE
Orders.[status] = 'PRINTED' AND
(Stock.SKU = OrderItems.SKU OR
AlternateSKUS.SKU = OrderItems.sku OR
Stock.BarCode = OrderItems.SKU) AND
Orders.channelId != 21
GROUP BY Stock.StockID, Stock.sku, Stock.ProductName
ORDER BY Qty DESC, Stock.sku
It runs much faster < 1 second.
There is a problem however. It appears that I have a recursion issue with my SUM() function in that it's multiplying the correct quantity, by how many "AlternateSKUs" records that exist for the same StockID.
For example, there if there is 1 Order, for 1 OrderItem, then it is being counted (QTY) as 4, because there are 4 AlternateSKUs for it. If a quantity of 2 was purchased for the same item, then QTY would return 8. Same for if there are other Orders for the same OrderItem, the number of Items is multiplied by the number of AlternateSKU records there are for it. E.G 3 seperate OrderItems belong to seperate Orders would yeild a QTY of 12 for the same item.
I realise that this is ultimately down to a poorly designed schema, however I have to work with what I've got.
How can I fix this?