Оптимизировать SQL-запрос с помощью агрегатной функции и условия обращения - PullRequest
0 голосов
/ 01 июля 2018

Интересно, есть ли лучший способ написать этот 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 голосов
/ 03 июля 2018

случай, когда должен быть частью 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
0 голосов
/ 01 июля 2018

Во-первых, я бы написал запрос более похожим на это:

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);

...