Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
fumitox Member Откуда: Сообщений: 38 |
Запрос такой:if exists (select 1 from Table1 t1 join Table2 t2 on t1.ID = t2.ID group by t1.ID having COUNT(t1.ID)>1) print 1 Результат: 0 строк за 20 сек. if exists (select 1 from Table1 t1 join Table2 t2 on t1.ID = t2.ID group by t1.ID having COUNT(t1.ID)>2) print 1 Результат: 0 строк за 0 сек. select 1 from Table1 t1 join Table2 t2 on t1.ID = t2.ID group by t1.ID having COUNT(t1.ID)>1 Результат: 0 строк за 0 сек. select 1 from Table1 t1 join Table2 t2 on t1.ID = t2.ID group by t1.ID Результат: 30000 строк за 0 сек. Я вот чет не могу понять как if exists усложняет запрос? |
10 апр 18, 17:34 [21327440] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
|
||
10 апр 18, 17:43 [21327463] Ответить | Цитировать Сообщить модератору |
fumitox Member Откуда: Сообщений: 38 |
Спасибо за ответ! Почему второй запрос не читает с диска? Где можно почитать про это? Первый раз с этим сталкиваюсь... Я решил проблему так: having(count)>1 => having(count)>=2 |
||
10 апр 18, 19:25 [21327638] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
|
||
10 апр 18, 21:33 [21327862] Ответить | Цитировать Сообщить модератору |
Дедушка Member Откуда: Город трёх революций Сообщений: 5114 |
fumitox, повыполняйте ваши запросы с холодным кешем dbcc dropcleanbuffers |
10 апр 18, 21:49 [21327894] Ответить | Цитировать Сообщить модератору |
fumitox Member Откуда: Сообщений: 38 |
Время выполнения запросов что я перечислил не зависит от последовательности, я могу проблемный запрос последним запустить, все равно он будет долго выполнятся, а остальные мгновенно... Мне нужен был только проблемный запрос, остальные я просто изменил для наглядности. после dbcc dropcleanbuffers - результат тот же... Если быть совсем точным, 6 секунд выполнялся этот запрос (без if exists мгновенно): if exists (select 1 from Table1 where ID in (select ID from Table2 group by ID having COUNT(ID)>1)) print 1 а вот этот висел 20 минут, после я его остановил (без if exists мгновенно): if exists (select 1 from Table1 t1 join Table2 t2 on t1.ID = t2.ID group by t1.ID having COUNT(t1.ID)>1) print 1 И я не понимаю что происходит, и дело явно не в кэше |
11 апр 18, 02:18 [21328197] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31779 |
Вы планы сравните, что ли. |
||
11 апр 18, 08:29 [21328335] Ответить | Цитировать Сообщить модератору |
Kopelly Member Откуда: Красноярск Сообщений: 289 |
ПО-моему exists ищет до первых данных, а не собирает все. За счет этого должен быть быстрее, но оптимизатор видимо думает по-другому. |
11 апр 18, 09:11 [21328382] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
Для exists будет генерироваться план, примерно такой как при использовании option(fast 1). И, скорее всего, таблицы там соединяются по NL. |
||
11 апр 18, 09:32 [21328422] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31779 |
А так получается неэквивалентно, причём теоретически if exists или select top 1 должно быть быстрее, чем просто select. А на практике.... :-( |
||
11 апр 18, 09:38 [21328433] Ответить | Цитировать Сообщить модератору |
aleks222 Member Откуда: Сообщений: 1236 |
Ответ неверен. Верный ответ: завязывайте с группировкой. |
||||
11 апр 18, 09:42 [21328443] Ответить | Цитировать Сообщить модератору |
fumitox Member Откуда: Сообщений: 38 |
Оставил запрос на ночь выполняться:if exists (select 1 from Table1 t1 join Table2 t2 on t1.ID = t2.ID group by t1.ID having COUNT(t1.ID)>1) print 1 Результат: 3 часа, 0 записей! Сравнил планы... Оргинал - index scan Без if exists - parallelism, index seek c if exists но having(count)>=2 - parallelism, index seek В общем все модификации кроме оригинала выполняются с параллелизмом, потому и так быстро. Вопрос... почему на оригинал не срабатывает?))) |
11 апр 18, 14:04 [21329530] Ответить | Цитировать Сообщить модератору |
Дедушка Member Откуда: Город трёх революций Сообщений: 5114 |
статистики на обоих таблицах обновляли? |
11 апр 18, 14:12 [21329561] Ответить | Цитировать Сообщить модератору |
fumitox Member Откуда: Сообщений: 38 |
Дедушка, Каждый день план обслуживания делается включая обновление статистики |
11 апр 18, 14:23 [21329622] Ответить | Цитировать Сообщить модератору |
Дедушка Member Откуда: Город трёх революций Сообщений: 5114 |
если возможно - приведите скрипты создания таблиц, - сколько строк в каждой - распределение данных (сколько у вас получается групп с count=1 и сколько >1) - скрипт создания индекса. попробую воспроизвести у себя... |
11 апр 18, 14:54 [21329831] Ответить | Цитировать Сообщить модератору |
aleks222 Member Откуда: Сообщений: 1236 |
Это оптимизатор толсто намекает на бездарно написанный запрос. |
||
11 апр 18, 15:21 [21329995] Ответить | Цитировать Сообщить модератору |
dies irae Member Откуда: Сообщений: 78 |
а статистика с fullscan обновляется? что если выполнить update statistics Table1 with fullscan update statistics Table2 with fullscan? |
||
11 апр 18, 15:26 [21330017] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31779 |
Видимо, хитрый оптимизатор думает, "а фигня, щас в самом начале найдётся count>1, чего мне на распараллеливание тратиться?" А там наверное мало дубликатов. для having(count)>=2 он такого предположения не делает... |
||
11 апр 18, 15:38 [21330111] Ответить | Цитировать Сообщить модератору |
fumitox Member Откуда: Сообщений: 38 |
dies irae,update statistics Table1 with fullscan update statistics Table2 with fullscan После выполнения включился параллелизм на проблемном запросе и теперь все со свистом выстреливает, спасибо! Пошел план обслуживания ковырять... Всем огромное спасибо за помощь следствию! ![]() |
11 апр 18, 16:00 [21330259] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |