Опасен ли этот намек на объединение?
-
03-07-2019 - |
Вопрос
Коллега попросил меня посмотреть на индексацию некоторых таблиц, потому что его запрос выполнялся очень долго.Больше часа.
select count(1)
from databaseA.dbo.table1
inner join databaseA.dbo.table2 on (table1.key = table2.key)
inner join databaseB.dbo.table3 on (table1.key = table3.key)
Обратите внимание на различные базы данных.Это выполнялось из базы данных
Таблицы 1 и 2 содержали более 2 миллионов записей.В таблице 3 было около дюжины записей.
Я просмотрел план запроса, и оптимизатор решил выполнить поиск по индексу вложенного цикла в таблицах 1 и 2 с таблицей Table3 в качестве управляющей таблицы!
Мое первое предположение состояло в том, что статистика была серьезно испорчена в таблицах 1 и 2, но перед обновлением статистики я попытался добавить подсказку о соединении таким образом:
select count(1)
from databaseA.dbo.table1
inner HASH join databaseA.dbo.table2 on (table1.key = table2.key)
inner join databaseB.dbo.table3 on (table1.key = table3.key)
Результаты были получены через 15 секунд.
Поскольку у меня было мало времени, я вернул ему результаты, но я беспокоюсь, что это может привести к проблемам в будущем.
Должен ли я вернуться к проблеме со статистикой и решить проблему таким образом?Мог ли плохой план запроса быть результатом объединения из отдельных баз данных?
Кто-нибудь может предложить мне несколько идей, основанных на вашем опыте?
Решение
Я бы сначала заподозрил статистику.
Как вы, без сомнения, знаете, в 99% случаев следует избегать подсказок о присоединении и использовать их только тогда, когда у вас есть доказательства того, что они абсолютно необходимы.
Другие советы
Сначала проверьте статистику и индексацию в таблице.Индексные подсказки могут вызвать проблемы.Если данные в таблицах изменятся, оптимизатор не сможет выбрать более эффективный план, поскольку вы вынудили его всегда использовать хэш.
Разве вложенный цикл не был бы наиболее подходящим?Возьмите 12 записей из таблицы 3, ,сопоставьте с 12 записями из таблицы 1, сопоставьте с 12 записями из таблицы 2.
В противном случае ваше хэш-соединение также обеспечивало бы упорядочение - это означает, что вы бы хэшировали 1 миллион записей из таблиц 1 и 2, а затем присоединились к 12 записям в таблице 3.
Я бы посмотрел статистику для обоих планов - и я бы заподозрил, что циклическое соединение на самом деле более эффективно, но было заблокировано или ваше хэш-соединение использовало кэшированные данные.
Но - да - в общем, подсказки о присоединении - это последнее средство.
Медленно выполняемый запрос, включающий связанные серверы, может иметь отношение к сортировке.Смотрите здесь некоторую справочную информацию: http://blogs.msdn.com/psssql/archive/2008/02/14/how-it-works-linked-servers-and-collation-compatibility.aspx Подсказка о хэш-соединении принудительно выполняет сортировку, так что это объясняет прирост производительности.
Вот как настроить параметры:
EXEC master.dbo.sp_serveroption
@server=N'databaseA',
@optname=N'collation compatible',
@optvalue=N'true'
EXEC master.dbo.sp_serveroption
@server=N'databaseA',
@optname=N'use remote collation',
@optvalue=N'false'
-Эдуде