+ 1 для Конрада, поскольку его ответ может быть всем, что вам нужно, и я повторно использовал часть его синтаксиса.
Проблема с Apply и CTE состоит в том, что они оцениваются для каждой строки в соединении a, b.
Я бы создал две временные таблицы. Чтобы представить максимальные строки и положить на них PK. Преимущество состоит в том, что эти два дорогостоящих запроса выполняются один раз, и соединение выполняется с ПК. Большая выгода от присоединения к ПК. Я ем накладные расходы на #temp, чтобы получить одну оценку и много PK.
Create table #Btab (int ID PK, ...)
insert into #Btab
WITH BTAB as
( SELECT * ,
row_nubmer() over (partition by b.id) rn
FROM
biggestTable
where ID <> 100
)
Select * from BTAB
Where RN = 1
order by ID
Create table #Bttab (int ID PK, ...)
insert into #Bttab
WITH BTTAB as
( SELECT * ,
row_nubmer() over (partition by id order by datetime desc) rn
FROM
biggestTable
where DateTime <> '1948-01-01 00:00:00.000' and value = 0
)
Select * from BTAB
Where RN = 1
order by ID
select
a.*,
b.*,
#Btab.*,
#Bttab.*
from
tableA a
join tableB b ON a.ID = b.UID
join *****
left join *******
....
....
....
left outer outer join #Btab
on #Btab.ID = a.ID
left outer outer join #Bttab
on #Bttab.ID = a.ID
where
..................
.................
P.S. Я исследую TVP над #TEMP для этого. TVP поддерживает PK и имеет меньше накладных расходов, чем #tmp. Но я не сравнивал их один на один в этом типе приложения.
Протестировано TVP через #TEMP и получено улучшение на 1/2 секунды (примерно время, необходимое для создания и удаления временной таблицы).