使用聚合函数和条件条件优化SQL查询

时间:2018-07-01 11:56:06

标签: sql sql-server performance sql-server-2008

我想知道是否还有更好的方法来编写此SQL。

CREATE TABLE #OrderTotals( [OrderID] uniqueIdentifier NULL, OrderTotal money 
NULL) 
CREATE NONCLUSTERED INDEX IDX_OrderTotals ON #OrderTotals(OrderID)

 Insert #OrderTotals (OrderID, OrderTotal)
    SELECT  o.Id,
    (CASE when o.OrderStatusId in (5,6,7) then  
    SUM(ISNULL(oi.[Price],0)* 
    ISNULL(oi.[InvoicedQty] ,0)+ ISNULL(oi.[TotalTax] ,0)) 

    When o.OrderStatusId not in (5,6,7) then
    SUM(ISNULL(oi.[Price],0)*(ISNULL(oi.[Quantity] ,0)
    - ISNULL(oi.[DeniedQuantity] ,0)) + ISNULL(oi. 
    [TotalTax] ,0)) end) as OrderTotal

    FROM orderItem oi
    inner join [Order] o on o.Id = oi.orderId
    WHERE  (o.Code = 'abc')
    group by o.id, o.OrderStatusId

我认为CASE会降低性能,这会使查询变慢。我在这里需要这种逻辑,只是想知道是否有更好的更有效的编写方法。

这是我的执行计划 enter image description here

2 个答案:

答案 0 :(得分:0)

首先,我将更像这样编写查询:

select o.Id,
       (case when o.OrderStatusId in (5, 6, 7)
             then sum(coalesce(oi.Price * oi.InvoicedQty, 0) +
                      coalesce(oi.TotalTax, 0)
                     ) 
             else sum(coalesce(oi.Price * (oi.Quantity - coalesce(oi.DeniedQuantity, 0)), 0) +
                      coalesce(oi.TotalTax, 0)
                     ) 
        end)
from [Order] o join
     orderItem oi
     on o.Id = oi.orderId
where o.Code = 'abc'
group by o.id, o.OrderStatusId;

我认为它仍然有太多的coalesce()调用,但是您没有提供足够的数据信息。

要对此进行优化,您需要在Order(Code, orderId)OrderItem(orderId)上建立索引;

答案 1 :(得分:0)

在什么情况下应该成为SUM之类的; (SUM(当.....时的情况)),

Insert #OrderTotals (OrderID, OrderTotal)
    SELECT  o.Id,
    SUM(
    CASE when o.OrderStatusId in (5,6,7) 
    then  
    ISNULL(oi.[Price]* oi.[InvoicedQty] ,0) + ISNULL(oi.[TotalTax] ,0)
ELSE
    ( ISNULL(oi.[Price] * oi.[Quantity] ,0) - ISNULL(oi.[DeniedQuantity] ,0) ) + ISNULL(oi.[TotalTax] ,0) 

     END) 
  as OrderTotal
FROM orderItem oi
    inner join [Order] o on o.Id = oi.orderId
    WHERE  (o.Code = 'abc')
    group by o.id, o.OrderStatusId