Ваш код RBAR ;выполняя один и тот же подзапрос 1, что очень неэффективно.
Вы беспокоитесь о «сортировке», но это само по себе не будет проблемой.Посмотрите дальше вверх и налево от плана;к вложенному циклу.Посмотрите жирную строку ввода сверху и тонкую чуть ниже.По сути, вы очень часто обращаетесь к своему сорту.
Предложение: попробуйте использовать решение на основе множеств.«Подготовьте» данные, которые требуются для предложения WHERE, «заранее», чтобы вы могли исключить RBAR.Представьте, что у вас есть LatestStatus
в виде таблицы со столбцами ControlNo
и StatusID
.Было бы намного проще применить ваш фильтр;и Оптимизатор запросов должен быть в состоянии найти более эффективный общий план.
Вы можете настроить это с помощью CTE.
;with StatusByControlNo as (
SELECT ROW_NUMBER() OVER(PARTITION BY ControlNo ORDER BY Timestamp DESC) AS RowNo,
ControlNo, Timestamp, NewQuoteStatusID
FROM tblQuoteStatusChangeLog
) ...
/*Easy to get Latest status per ControlNo from here*/
SELECT ControlNo, NewQuoteStatusID
FROM StatusByControlNo
WHERE RowNo = 1
Теперь с несколькими настройками ваш запрос становится:
;with StatusByControlNo as (
SELECT ROW_NUMBER() OVER(PARTITION BY ControlNo ORDER BY Timestamp DESC) AS RowNo,
ControlNo, Timestamp, NewQuoteStatusID
FROM tblQuoteStatusChangeLog
)
SELECT
Q.ControlNo,
sum(fid.amtbilled) as Premium
FROM
tblQuotes Q
inner join tblFin_Invoices FI
on Q.QuoteID = FI.QuoteID and FI.failed = 0
inner join tblFin_InvoiceDetails FID
on FI.InvoiceNum = FID.InvoiceNum
inner join StatusByControlNo S
on S.ControlNo = Q.ControlNo and S.RowNo = 1
WHERE
S.ControlNo <> 12
Group by Q.ControlNo
Само собой разумеется, вы можете попробовать несколько вариантов этого.Но основной принцип заключается в сокращении RBAR и поиске решений, которые более «основаны на множествах».