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

Откуда:
Сообщений: 67
Добрый день!

Пытаюсь оптимизировать один запрос, где соединяются две большие таблицы.
Сервер выбирает для этого оператор HASH JOIN, что для моего случая нормально.
Вопрос в следующем: Помимо соединения по хэш, в операторе присутствует еще явная проверка на равенство соединяемых полей, что отражается в разделе probe residual (там обычно всплывают предикаты, которые существуют помимо условия джоина)

У меня подозрение, что на такое "двойное" сравнение (по хэш, затем по реальным значениям) тратится большая часть времени в плане выполнения (и сам оператор занимает 63% в плане)

Читал, что такое может быть, если типы соединяемых полей разные (борьба с хэш коллизией), но у меня они одинаковые.

на примере оператора hash join в плане запроса:

Hash Keys probe:
...dbo.[table2].[col1], ...dbo.[table2].[col2]

Probe Residual:
...dbo.[table1].[col1]=...dbo.[table2].[col1] AND
...dbo.[table1].[col2]=...dbo.[table2].[col2]
2 апр 14, 14:23    [15821504]     Ответить | Цитировать Сообщить модератору
 Re: HASH JOIN probe residual  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
KostaRico
Читал, что такое может быть, если типы соединяемых полей разные (борьба с хэш коллизией), но у меня они одинаковые.
Этого мало, нужно чтобы было NOT NULL.

Join Performance, Implicit Conversions, and Residuals
2 апр 14, 15:21    [15821958]     Ответить | Цитировать Сообщить модератору
 Re: HASH JOIN probe residual  [new]
KostaRico
Member

Откуда:
Сообщений: 67
Уточнил, они точно NOT NULL.
2 апр 14, 15:24    [15821981]     Ответить | Цитировать Сообщить модератору
 Re: HASH JOIN probe residual  [new]
KostaRico
Member

Откуда:
Сообщений: 67
Правда второе поле в join имеет тип varchar(20).
Возможно , что из-за текстового поля без проверки на коллизии хэша не получится?
2 апр 14, 15:30    [15822030]     Ответить | Цитировать Сообщить модератору
 Re: HASH JOIN probe residual  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
KostaRico,

Тип не важен, комплексные предикаты так обрабатываются.Вообще, если только у вас там не мегамонстр в соединении типа такого:
+
Картинка с другого сайта.

- то, имхо, не туда вы копаете.

Hash Join имеет гораздо более вероятные проблемные места, например spill или ожидания памяти. Кроме того, стоимость оператора в плане говорит только об оценке, если оценка ошибочна, возможно, вы смотрите не на тот оператор плана. Ну и, наконец, дело может быть вообще не в плане.
2 апр 14, 16:02    [15822322]     Ответить | Цитировать Сообщить модератору
 Re: HASH JOIN probe residual  [new]
KostaRico
Member

Откуда:
Сообщений: 67
Спасибо за ответ!

У меня не такой монстр. Соединяю только по двум полям, int и nvarchar(20)
Проверил, если соединять только по полю int, probe residual уходит.

Все таки я думаю, что в запросе основное время уходит на join.
2 апр 14, 16:20    [15822487]     Ответить | Цитировать Сообщить модератору
 Re: HASH JOIN probe residual  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
KostaRico,

Может и на Join, но не обязательно на проверку residual.

Хэш джоин бывает медленный, если сливает данные на диск, посмотрите профайлером Hash Warnings (в 2102 это значком в действительном плане уже показывается, без профайлера можно увидеть). Он у вас параллельный? Может быть с параллелизмом какие-то проблемы. Таблицы большие, говорите, памяти много требует этот джоин, достаточно ее есть в системе, чтобы выделить сразу?

Гадать можно долго, но лучше всего, особенно если проблема воспроизводится, посмотреть ожидания, при помощи расширенных событий, например. Тогда вы узнаете почему так долго и будет понятно, план это или нет, память или нет и т. д.
2 апр 14, 16:29    [15822567]     Ответить | Цитировать Сообщить модератору
 Re: HASH JOIN probe residual  [new]
KostaRico
Member

Откуда:
Сообщений: 67
В настройках сервера Maximum Server Memory стоит 150 000 MB

Таблица для Hash Build ветки около 36 млн. записей
Таблица для PROBE около 200 млн.

А как в 2008 R2 идентифицировать, хватает ли памяти хэшу, или он tempdb начинает использовать?
Имею доступ только к профайлеру (но не к performance counters)
2 апр 14, 16:51    [15822745]     Ответить | Цитировать Сообщить модератору
 Re: HASH JOIN probe residual  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
KostaRico
А как в 2008 R2 идентифицировать, хватает ли памяти хэшу, или он tempdb начинает использовать?
Имею доступ только к профайлеру (но не к performance counters)

SomewhereSomehow
если сливает данные на диск, посмотрите профайлером Hash Warnings

Если ничего не проясниться, то смотрите ожидания при помощи xEvents.
2 апр 14, 17:49    [15823135]     Ответить | Цитировать Сообщить модератору
 Re: HASH JOIN probe residual  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
KostaRico
В настройках сервера Maximum Server Memory стоит 150 000 MB

Таблица для Hash Build ветки около 36 млн. записей
Таблица для PROBE около 200 млн.
Из 150Гб, сервер для одного запроса по умолчанию может использовать только около 25% от 75% доступной памяти. Что при ваших 150*0.75*0.25 = 28Гб. Скорее всего это вполне достаточно, но сервер может ошибиться в оценках, тогда он запросит меньше чем нужно и получим spill to tempdb.
SomewhereSomehow
KostaRico
А как в 2008 R2 идентифицировать, хватает ли памяти хэшу, или он tempdb начинает использовать?
Имею доступ только к профайлеру (но не к performance counters)

SomewhereSomehow
если сливает данные на диск, посмотрите профайлером Hash Warnings

Если ничего не проясниться, то смотрите ожидания при помощи xEvents.
Размах слива в tempdb непосредственно в момент выполнения вашего запроса еще можно помониторить вот так:

select 
  tsu.session_id, tsu.request_id, 
  SUM(tsu.internal_objects_alloc_page_count- tsu.internal_objects_dealloc_page_count)/128. AS tempdb_internal_current_mb
from sys.dm_db_task_space_usage tsu 
where tsu.internal_objects_alloc_page_count > 0
group by tsu.session_id, tsu.request_id 

Еще можно глянуть сколько было бы идеально получить памяти под выполнение запроса, а так же сколько запрошено и реально использовано:
select * from sys.dm_exec_query_memory_grants where session_id = @session_id -- your session_id
2 апр 14, 22:19    [15824149]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить