Эта часть запроса делает его довольно плохим, к сожалению, не видно пути, оптимизируйте.Abysmal performance - Hash join берет> 80% стоимости запроса в SQL Server 2012
update #db set contents = i.contents
from (select distinct
(select max(ac.contents) from ##dwv d
left join ##calendar c on 1=1
left join #db ac on d.id = ac.id
and c.ReportingPeriod = ac.DateValue and ac.Data_Type = 'ActivePeriod'
where d.ID = dd.id and month_number >= (cc.month_number-3)
and month_number <= cc.month_number) contents
,dd.id
,cc.ReportingPeriod
from #db dd
left join ##calendar cc on cc.ReportingPeriod = dd.DateValue
where dd.Data_Type = 'ActivePeriod'
)i
where i.id = #db.id and i.ReportingPeriod = #dashboard.DateValue
Я пытался сначала слить его, но не пошел куда-то быстро, и этот щенок появился.
Идея заключается в том, чтобы отметить каждого клиента активным в любой заданный период (год, месяц в формате «YYYYMM») в соответствии с конкретным алгоритмом, поэтому для каждого клиента, который соответствует критериям отчета, мне нужно иметь строку, которая будет скажите мне, был ли он активным (то есть: недавно купил).
#db
является временной таблицей, где я собираю все данные, которые будут впоследствии использоваться для агрегатов для получения отчета - большой стола в нескольких миллионов строк, в зависимости от сроков:
Create table #db
(
C_P varchar(6)
,Data_Type varchar(20)
,id int
,contents int
,DateValue varchar(10)
)
##dwv
является температурой таблица, где я сбрасываю результат выбора на большом представлении (который сам очень медленный) занимает около 2,4 млн. строк
##calendar
- это специальная таблица, которая хранит каждый период, когда отчет охватывает тот же формат ' ГГГГММ:
select CONVERT(char(6), cast(@startdate as date), 112) "CP"
,CONVERT(char(6), cast(PKDate as date), 112) "RP"
,(ROW_NUMBER() over (order by (CONVERT(char(6), cast(PKDate as date), 112)) asc))-1
as month_number
into ##calendar
from [calendar].[dbo].[days]
where PKDate between @startdate and @enddate2
group by CONVERT(char(6), cast(PKDate as date), 112)
план запроса говорит мне, что бит c.ReportingPeriod = ac.DateValue
является cuplrit - занимает 88% от стоимости подзапросов с ним, что в свою очередь приходится 87% от стоимости всего запроса.
Что я не вижу здесь и как я могу улучшить это?
Добавили ли вы индексы в свои временные таблицы? Вы уверены, что вы должны сбросить все эти данные в временные таблицы вместо того, чтобы использовать существующие таблицы и индексы?Поделитесь своими планами выполнения, используя [Paste The Plan @ brentozar.com] (https://www.brentozar.com/pastetheplan/) – SqlZim
Будьте очень осторожны с использованием глобальных временных таблиц. Там много проблем с параллелизмом. И почему левые соединяются с 1 = 1 как единственный предикат? Разве это не было бы проще в качестве креста? –
Выполняется обновление, основанное на соединении с отдельным в результирующем наборе с выражением столбца, которое использует коррелированный подзапрос с агрегированием в правой таблице левого соединения. Можете ли вы опубликовать определение планов выполнения и всех таблиц и объяснить бизнес-проблему, которую вы пытаетесь решить? Нам может быть несколько сложно разгадать этот запрос. –