我的一个查询存在性能问题。
慢查询:
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
返回结果大约需要11秒。
我尝试优化查询,从WHERE子句中删除嵌套的SELECT并提出这个:
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
运行速度更快< 1秒。
但是有一个问题。我的SUM()函数似乎有一个递归问题,因为它将正确的数量乘以" AlternateSKUs"存在于同一StockID的记录。
例如,如果有1个Order,对于1个OrderItem,那么它被计为(QTY)为4,因为它有4个AlternateSKU。如果为同一项目购买了数量2,那么QTY将返回8.如果同一OrderItem有其他订单,则相同的项目数量乘以它的AlternateSKU记录数量。 E.G 3单独的OrderItems属于单独的订单,对同一项目的数量为12。
我意识到这最终归结为一个设计不佳的架构,但我必须使用我所拥有的。
我该如何解决这个问题?
答案 0 :(得分:1)
这一切归结为[CMRC_Stock]
和[OrderItems]
之间的关系。可以使用具有多个替代SKU的库存SKU。每个订单商品的数量将乘以替代SKU的数量。
我在下面所做的是重构您的原始查询,以便首先检索SKU / Stock ID的不同列表,然后可以将[OrderItems]
加入[CMRC_Stock]
:
WITH StockSKUs([StockID],[SKU]) AS (
SELECT
[StockID],[SKU]
FROM [CMRC_Stock]
UNION
SELECT
[StockID],[BarCode]
FROM [CMRC_Stock]
UNION
SELECT
[StockID],[SKU]
FROM [AlternateSKUs]
)
SELECT
Orders.[order-id],
Stock.StockID,
Stock.sku AS SKU,
Stock.ProductName AS PRODUCT,
SUM(OrderItems.[quantity-purchased]) as Qty
FROM
Orders
JOIN OrderItems
ON Orders.[order-id] = OrderItems.[order-id]
JOIN StockSKUs
ON OrderItems.[SKU] = StockSKUs.[SKU]
JOIN CMRC_Stock as Stock
ON StockSKUs.[StockID] = Stock.[StockID]
WHERE
Orders.[status] = 'PRINTED'
AND Orders.channelId != 21
GROUP BY Orders.[order-id], Stock.StockID, Stock.SKU, Stock.ProductName
ORDER BY Qty DESC, Stock.SKU
随后将出现一个SQL小提琴。