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

Откуда:
Сообщений: 1366
Здравствуйте.
Есть такой скрипт

  IF exists(	
select K1.keyRKD --*, K1.OKD, K2.OKD, K1.OND, K2.OND, K1.PSum, K2.PSum , K1.RSum, K2.RSum
            FROM Kassa_RKD_E K1 
            INNER JOIN Kassa_RKD_View_E2_tbl_tmp K2 ON K1.dat = K2.dat
		            AND K1.keyOH=K2.keyOH AND K1.kodF=K2.kodF AND K1.KartAcc=K2.KartAcc AND K1.KartNom=K2.KartNom AND K1.keyCA=K2.keyCA
            WHERE ROUND(K1.OKD-K2.OKD,2)<>0 
            OR
	            ROUND(K1.OND-K2.OND,2)<>0 OR
	            ROUND(K1.PSum-K2.PSum,2)<>0 OR
	            ROUND(K1.RSum-K2.RSum,2)<>0 
	            
	            ) print '1'

select K1.*, K1.OKD, K2.OKD, K1.OND, K2.OND, K1.PSum, K2.PSum , K1.RSum, K2.RSum
            FROM Kassa_RKD_E K1 
            INNER JOIN Kassa_RKD_View_E2_tbl_tmp K2 ON K1.dat = K2.dat
		            AND K1.keyOH=K2.keyOH AND K1.kodF=K2.kodF AND K1.KartAcc=K2.KartAcc AND K1.KartNom=K2.KartNom AND K1.keyCA=K2.keyCA
            WHERE ROUND(K1.OKD-K2.OKD,2)<>0 
            OR
	            ROUND(K1.OND-K2.OND,2)<>0 OR
	            ROUND(K1.PSum-K2.PSum,2)<>0 OR
	            ROUND(K1.RSum-K2.RSum,2)<>0 


У таблицы Kassa_RKD_View_E2_tbl_tmp нет индексов вообще

НЕПОНЯТНОСТЬ:
при построении плана для блока IF EXISTS() оптимизатор предполагает, что количество строк для PK_Kassa_RKD_E будет 2,7 и выбирается соединение LOOP JOIN. От этого операция IF EXISTS выполняется 1 час!!!
Но тот же самый запрос, выполненный вне конструкции IF EXISTS уже строится по другому. И для PK_Kassa_RKD_E предполагаемое количество строк уже берется реальное = 199 999. Запрос выполняется меньше секунды.

Знаю, что спасает подсказка Использовать HASH JOIN, но больше интересует почему берется неверное предположение о количестве строк.

План запроса прикладываю

К сообщению приложен файл (ХитрыйПлан.sqlplan - 63Kb) cкачать
8 окт 18, 03:06    [21697638]     Ответить | Цитировать Сообщить модератору
 Re: План выполнения запроса непонятен  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
Диам,

Это называется row goal.
8 окт 18, 09:09    [21697702]     Ответить | Цитировать Сообщить модератору
 Re: План выполнения запроса непонятен  [new]
Диам
Member

Откуда:
Сообщений: 1366
TaPaK,
почитал. Спасибо.
А как лечить, если не явной подсказкой INNER HASH JOIN ?
8 окт 18, 16:24    [21698327]     Ответить | Цитировать Сообщить модератору
 Re: План выполнения запроса непонятен  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
Диам
TaPaK,
почитал. Спасибо.
А как лечить, если не явной подсказкой INNER HASH JOIN ?

я лечу выносом всего в переменную, потом проверяю простот if @a = 1
8 окт 18, 16:47    [21698388]     Ответить | Цитировать Сообщить модератору
 Re: План выполнения запроса непонятен  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1172
Диам,

для SQL 2016 SP1 есть

OPTION (USE HINT('DISABLE_OPTIMIZER_ROWGOAL')),

для версий ниже можно использовать trace-флаг 4138
8 окт 18, 18:38    [21698519]     Ответить | Цитировать Сообщить модератору
 Re: План выполнения запроса непонятен  [new]
Владимир Затуливетер
Member

Откуда:
Сообщений: 427
Диам
А как лечить, если не явной подсказкой INNER HASH JOIN ?

а в чем проблема простовыставить хин hash join?
это ведь то что вам нужно.
не вижу смысла что-то еще делать, всего две таблицы без индексов, ожидаем hash join, и больше ничего.
8 окт 18, 21:22    [21698657]     Ответить | Цитировать Сообщить модератору
 Re: План выполнения запроса непонятен  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
felix_ff
Диам,

для SQL 2016 SP1 есть

OPTION (USE HINT('DISABLE_OPTIMIZER_ROWGOAL')),

для версий ниже можно использовать trace-флаг 4138

Есть небольшие проблемы с хинтом... Некуда поставить :)
8 окт 18, 21:51    [21698687]     Ответить | Цитировать Сообщить модератору
 Re: План выполнения запроса непонятен  [new]
invm
Member

Откуда: Москва
Сообщений: 9125
Диам
А как лечить, если не явной подсказкой INNER HASH JOIN ?
Например так:
IF exists(	
 select
  *
 from
  (
   select
    row_number() over (order by (select 1)) 
            FROM Kassa_RKD_E K1 
            INNER JOIN Kassa_RKD_View_E2_tbl_tmp K2 ON K1.dat = K2.dat
		            AND K1.keyOH=K2.keyOH AND K1.kodF=K2.kodF AND K1.KartAcc=K2.KartAcc AND K1.KartNom=K2.KartNom AND K1.keyCA=K2.keyCA
            WHERE ROUND(K1.OKD-K2.OKD,2)<>0 
            OR
	            ROUND(K1.OND-K2.OND,2)<>0 OR
	            ROUND(K1.PSum-K2.PSum,2)<>0 OR
	            ROUND(K1.RSum-K2.RSum,2)<>0
   ) t(rn) 
  where
   rn > 0	            
) print '1'
8 окт 18, 22:25    [21698726]     Ответить | Цитировать Сообщить модератору
 Re: План выполнения запроса непонятен  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
invm
Диам
А как лечить, если не явной подсказкой INNER HASH JOIN ?
Например так:
А просто count(*) в таких случаях разве не срабатывает?
9 окт 18, 23:18    [21699864]     Ответить | Цитировать Сообщить модератору
 Re: План выполнения запроса непонятен  [new]
Диам
Member

Откуда:
Сообщений: 1366
Mind, помогает все, что исключает exists()
11 окт 18, 11:25    [21701330]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить