Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Диам Member Откуда: Сообщений: 1480 |
Здравствуйте. Есть такой скрипт 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] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6801 |
Диам, Это называется row goal. |
8 окт 18, 09:09 [21697702] Ответить | Цитировать Сообщить модератору |
Диам Member Откуда: Сообщений: 1480 |
TaPaK, почитал. Спасибо. А как лечить, если не явной подсказкой INNER HASH JOIN ? |
8 окт 18, 16:24 [21698327] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6801 |
я лечу выносом всего в переменную, потом проверяю простот if @a = 1 |
||
8 окт 18, 16:47 [21698388] Ответить | Цитировать Сообщить модератору |
felix_ff Member Откуда: Moscow Сообщений: 1692 |
Диам, для SQL 2016 SP1 есть OPTION (USE HINT('DISABLE_OPTIMIZER_ROWGOAL')), для версий ниже можно использовать trace-флаг 4138 |
8 окт 18, 18:38 [21698519] Ответить | Цитировать Сообщить модератору |
Владимир Затуливетер Member Откуда: Сообщений: 427 |
а в чем проблема простовыставить хин hash join? это ведь то что вам нужно. не вижу смысла что-то еще делать, всего две таблицы без индексов, ожидаем hash join, и больше ничего. |
||
8 окт 18, 21:22 [21698657] Ответить | Цитировать Сообщить модератору |
TaPaK Member Откуда: Kiev Сообщений: 6801 |
Есть небольшие проблемы с хинтом... Некуда поставить :) |
||
8 окт 18, 21:51 [21698687] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
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] Ответить | Цитировать Сообщить модератору |
Mind Member Откуда: Лучший город на Земле Сообщений: 2322 |
|
||||
9 окт 18, 23:18 [21699864] Ответить | Цитировать Сообщить модератору |
Диам Member Откуда: Сообщений: 1480 |
Mind, помогает все, что исключает exists() |
11 окт 18, 11:25 [21701330] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |