- Интересно, если
HAVING SUM( ABS(ri.netamount)) != 0
появится достаточно рано, я предполагаю, что это происходит из-за порядка операций Compute Scalar и Filter, выполняемых в плане запроса ... все же, я бы предпочел быть более явным об этом.
- Как уже упоминал Иван Старостин, нет необходимости
GROUP BY
в столбце AsOfDate
, потому что это константа.
- Поскольку оптимизатор предпочитает использовать объединение слиянием, мы могли бы попытаться избежать двух сортировок, добавив индекс покрытия
1012 *, например *
CREATE INDEX idx_test ON ReconCollateralExternal (AsOfDate, PortofolioCode) INCLUDE (NetAmount)
CREATE INDEX idx_test ON ReconCollateralInternal (AsOfDate, PortofolioCode) INCLUDE (NetAmount)
Имейте в виду, что такого понятия, как бесплатный обед, не существует: индексы могут сделать запрос (немного) быстрее (?), Но это окажет (небольшое) влияние на производительность операций вставки / обновления / удаления на столе в другом месте!
Тогда запрос будет выглядеть примерно так:
DECLARE @asofdate DATE = '2018-08-29';
DECLARE @threshold INT = 25
SELECT Portfoliocode,
AsOfDate = @asofdate,
SumAbsEmcMtm,
SumAbsBrokerMtm,
100 * (SumAbsEmcMtm - SumAbsBrokerMtm) / SumAbsEmcMtm PctMtmBreak
FROM (SELECT ri.Portfoliocode,
SUM( ABS(ri.NetAmount)) SumAbsEmcMtm,
SUM( ABS(re.NetAmount)) SumAbsBrokerMtm
-- 100 * (SUM (ABS(ri.NetAmount)) - SUM( ABS(re.netamount))) / SUM( ABS(ri.netamount)) PctMtmBreak
FROM ReconCollateralExternal ri
JOIN ReconCollateralInternal re
ON re.PortfolioCode = ri.PortfolioCode
AND re.AsOfDate = @asofdate -- ri.AsOfDate
WHERE ri.asofdate = @asofdate
GROUP BY ri.PortfolioCode
HAVING SUM( ABS(ri.NetAmount)) != 0
) A
WHERE ABS(100 * (SumAbsEmcMtm - SumAbsBrokerMtm) / SumAbsEmcMtm ) >= @threshold
ORDER BY ABS(100 * (SumAbsEmcMtm - SumAbsBrokerMtm) / SumAbsEmcMtm ) DESC;
PS: имейте в виду, что при развертывании этого кода на чувствительном к регистру сервере он не будет компилироваться, например, PortofolioCode! = Portofoliocode