Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Баг оптимизатора?  [new]
aleksrov
Member

Откуда:
Сообщений: 948
Всем привет! В общем такая вещь, делаю Merge таблицы
MERGE [DWH].[dbo].[FactContactLog] as t
USING
(
SELECT cs.[Country]
      ,cs.[ContactLogID]
      ,cs.[PromiseID]
      ,cs.[NumberContract]
	  ,fa.ContractID
	  ,cs.[DebtID]
      ,cs.[PhoneIDContact]
	  ,dcr.ContactResultKey
	  ,st.staffkey
	  ,case when fp.PhonesAttributeKey is null then (select PhonesAttributeKey from [DWH].[dbo].[DimPhonesAttribute] where [ActualFlag] = 0 and [ContactType] = 'NA' and [Relation] = 'NA' and Source = 'Contact') else fp.PhonesAttributeKey end as PhonesAttributeKey
	  ,fa.ApplicationAttributeKey
	  ,fa.ApplicationKey
	  ,fa.BorrowerKey
	  ,fa.GeographyKey
      ,cs.[Description]
      ,cs.[ContactDate]
      ,cs.[CreatePromiseDate]
      ,cs.[PromiseDate]
      ,cs.[PromiseSum]	 
  FROM [Staging].[dbo].[ContactLog_Stage] as cs
  left join [DWH].[dbo].[DimContactResult] as dcr
  on cs.result = dcr.Code
  left join [DWH].[dbo].[DimStaff] as st
  on cs.userid = st.staffidcontact 
  left join [DWH].[dbo].[FactContract] as fa
  on cs.NumberContract = fa.NumberContract and cs.Country = fa.Country
  left join [DWH].[dbo].FactPhones as fp 
  on cs.PhoneIDContact = fp.PhoneIDContact 
  ) as s
  on t.ContactLogID = s.ContactLogID
  when not matched by target then insert 
  ([Country],[ContactLogID],[PromiseID],[NumberContract],[ContractID],[DebtID],[ContactPhoneID],[StaffKey],[ContactResultKey],[PhonesAttributeKey],[ApplicationKey],[ApplicationAttributeKey],[BorrowerKey]
      ,[GeographyKey],[ContactDate],[CreatePromiseDate],[PromiseDate],[Description],[PromiseSum])
values
(s.[Country],s.[ContactLogID],s.[PromiseID],s.[NumberContract],s.[ContractID],s.[DebtID],s.[PhoneIDContact],s.[StaffKey],s.[ContactResultKey],s.[PhonesAttributeKey],s.[ApplicationKey],s.[ApplicationAttributeKey],s.[BorrowerKey]
      ,s.[GeographyKey],s.[ContactDate],s.[CreatePromiseDate],s.[PromiseDate],s.[Description],s.[PromiseSum]);

То что апдейтиь факты зло я знаю, в данном случае так надо.
Так вот, оптимизатор высирает такой план.
В Stage 21 млн строк, все норм, когда он доходит до join с FactPhones на выходе с HashJoin он выдает просто безумную цифру, причем он сканит PK, хотя у меня есть уникальный фильтрованный индекс по PhoneIDContact с включенным PhonesAttributeKey, если же задать использовать этот индекс через хинт то вываливается
Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query without specifying any hints and without using SET FORCEPLAN.
Прикол в том что из-за этого запроса tempdb растет с 20 до 100 гигов и останвливается (у меня ограничение но месту).
Вопрос почему tempdb растет и почему он игнорит покрывающий индекс?

К сообщению приложен файл (Plan.7z - 12Kb) cкачать
22 ноя 18, 23:28    [21742200]     Ответить | Цитировать Сообщить модератору
 Re: Баг оптимизатора?  [new]
aleksrov
Member

Откуда:
Сообщений: 948
Забыл
Microsoft SQL Server 2017 (RTM-CU5) (KB4092643) - 14.0.3023.8 (X64) Mar 2 2018 18:24:44 Copyright (C) 2017 Microsoft Corporation Enterprise Edition: Core-based Licensing (64-bit) on Windows Server 2016 Datacenter 10.0 <X64> (Build 14393: ) (Hypervisor)
22 ноя 18, 23:34    [21742202]     Ответить | Цитировать Сообщить модератору
 Re: Баг оптимизатора?  [new]
aleksrov
Member

Откуда:
Сообщений: 948
Причем нефильтрованный индекс оптимизатор берет, но все ровно выдает такое ожидание по кол-ву строк.
22 ноя 18, 23:39    [21742204]     Ответить | Цитировать Сообщить модератору
 Re: Баг оптимизатора?  [new]
aleks222
Member

Откуда:
Сообщений: 849
Стисняюсь спросить: занафига тут merge?

 
select * into #FactContactLog
     from [ваш монстрик] as s
     where not exists( select * from [DWH].[dbo].[FactContactLog] as t where  t.ContactLogID = s.ContactLogID ); 
-- если будет медленно - вставляем только основную таблицу, остальное добиваем апдэйтом.
 
  alter table #FactContactLog add primary key(ContactLogID);


  merge [DWH].[dbo].[FactContactLog] as t using #FactContactLog as s
  ...


"хотя у меня есть уникальный фильтрованный индекс по PhoneIDContact с включенным PhonesAttributeKey"

left join ( select {воспроизведите тут ТОЧНЫЙ перечень полей фильтрованного индекса} from [DWH].[dbo].FactPhones where {воспроизведите тут ТОЧНОЕ условие фильтрации индекса} ) as fp
23 ноя 18, 08:22    [21742314]     Ответить | Цитировать Сообщить модератору
 Re: Баг оптимизатора?  [new]
aleksrov
Member

Откуда:
Сообщений: 948
aleks222,

Т.к. дальше есть кусок на update, я его просто не вставил, поэтому и merge.

Почему индекс не использовал нашел, ошибки в источнике, строки которых там не должно было быть, отсюда на выходе и такое кол-во строк.
23 ноя 18, 16:32    [21743104]     Ответить | Цитировать Сообщить модератору
 Re: Баг оптимизатора?  [new]
aleksrov
Member

Откуда:
Сообщений: 948
aleks222,

И Merge отрабатывает быстро, в день пару тысяч строк приходит, новых единицы, 90% надо апдейт делать, на нужных полях есть индексы, занимает пару секунд.
23 ноя 18, 16:34    [21743107]     Ответить | Цитировать Сообщить модератору
 Re: Баг оптимизатора?  [new]
aleksrov
Member

Откуда:
Сообщений: 948
aleksrov
aleks222,

И Merge отрабатывает быстро, в день пару тысяч строк приходит, новых единицы, 90% надо апдейт делать, на нужных полях есть индексы, занимает пару секунд.


В таргете 40 млн.
23 ноя 18, 16:34    [21743109]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить