Опасно ли это соединение?
Коллега попросил меня посмотреть на индексацию некоторых таблиц, потому что его запрос выполнялся очень долго. Больше часа.
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 миллионов записей. В Table3 было около десятка записей или около того.
Я посмотрел на план запроса, и оптимизатор решил выполнить поиск индекса по вложенным циклам в таблицах 1 и 2 с таблицей 3 в качестве движущей таблицы!
Мое первое предположение состояло в том, что статистика была серьезно испорчена в таблицах 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 секунд.
Поскольку у меня было мало времени, я передал результаты обратно ему, но я боюсь, что это может привести к проблемам в будущем.
Должен ли я вернуться к проблеме статистики и решить проблему таким образом? Может ли неправильный план запроса быть результатом объединения из отдельных баз данных?
Может кто-нибудь предложить мне несколько идей, основанных на вашем опыте?
4 ответа
Я бы сначала заподозрил статистику.
Как вы, несомненно, знаете, подсказок о присоединении следует избегать в 99% случаев и использовать только тогда, когда у вас есть доказательства того, что они абсолютно необходимы.
Медленно выполняющийся запрос, связанный со связанными серверами, может быть связан с сопоставлением. Смотрите здесь для некоторой предыстории: 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'
-Edoode
Проверяйте статистику и индексацию по таблице в первую очередь. Индексные подсказки могут вызвать проблемы. Если данные в таблицах изменятся, оптимизатор не сможет выбрать более эффективный план, поскольку вы заставили его всегда использовать хэш.
Разве вложенный цикл не будет наиболее подходящим? Возьмите 12 записей из таблицы 3, сопоставьте с 12 записями в таблице 1, сопоставьте с 12 записями в таблице 2.
В противном случае, ваше хеш-соединение будет также обеспечивать порядок - то есть вы хешируете 1 миллион записей из Таблицы 1 и Таблицы 2, а затем присоединитесь к 12 записям в Таблице 3.
Я бы посмотрел статистику для обоих планов - и я подозреваю, что объединение циклов на самом деле более эффективно, но было заблокировано или ваше хеш-соединение использовало преимущества кэшированных данных.
Но - да - в общем, советы о присоединении являются последним средством.