Опасно ли это соединение?

Коллега попросил меня посмотреть на индексацию некоторых таблиц, потому что его запрос выполнялся очень долго. Больше часа.

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.

Я бы посмотрел статистику для обоих планов - и я подозреваю, что объединение циклов на самом деле более эффективно, но было заблокировано или ваше хеш-соединение использовало преимущества кэшированных данных.

Но - да - в общем, советы о присоединении являются последним средством.

Другие вопросы по тегам