连接表

时间:2015-06-23 15:22:59

标签: sql sql-server database performance

我的一个查询存在性能问题。

慢查询:

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。

我意识到这最终归结为一个设计不佳的架构,但我必须使用我所拥有的。

我该如何解决这个问题?

1 个答案:

答案 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小提琴。