ВНУТРЕННЕЕ СОЕДИНЕНИЕ на таблице связанных серверов намного медленнее, чем подзапрос - PullRequest
5 голосов
/ 26 января 2012

Я столкнулся с этой очень странной ситуацией и подумал, что брошу это в толпу, чтобы узнать ПОЧЕМУ.

У меня есть запрос, который присоединяется к таблице на связанном сервере:

select a.*, b.phone
from table_a a, 
join remote.table_b b on b.id = a.id
 (lots of data on A, but very few on B)

этот запрос говорил вечно (даже не узнал фактического времени выполнения), и именно тогда я заметил, что B не имеет индекса, поэтому я добавил его, но это не решило проблему. Наконец, в отчаянии я попытался:

select a.*, b.phone
from table_a a, 
join (select id, phone from remote.B) as b on b.id = a.id

Эта версия запроса, по моему мнению, как минимум, должна иметь те же результаты, но вот, он отвечает немедленно!

Есть идеи, почему один зависает, а другой быстро обрабатывается? И да, я ждал, чтобы убедиться, что индекс был построен, прежде чем запускать оба.

Ответы [ 4 ]

4 голосов
/ 26 января 2012

Это потому, что иногда (очень часто) планы выполнения, автоматически генерируемые ядром сервера sql, не так хороши и очевидны, как хотелось бы. Вы можете посмотреть на план выполнения в обеих ситуациях. Я предлагаю использовать подсказку в первом запросе, что-то вроде этого: INNER MERGE JOIN.

Вот еще немного информации об этом:

http://msdn.microsoft.com/en-us/library/ms181714.aspx

3 голосов
/ 26 января 2012

Для связанных серверов 2-й вариант выполняет предварительную выборку всех данных локально и выполняет объединение, поскольку 1-й вариант может выполнить inner loop join отправку туда и обратно на связанный сервер для каждой строки в A

1 голос
/ 26 января 2012

Я просто собираюсь угадать здесь.Когда вы обращаетесь к remote.b, это таблица на другом сервере?

Если это так, причина, по которой второй запрос выполняется быстрее, заключается в том, что вы делаете один запрос к другому серверу и получаете все необходимые поля изб, перед обработкой данных.В первом запросе вы обрабатываете данные и одновременно делаете несколько запросов к другому серверу.

Надеюсь, это поможет вам.

1 голос
/ 26 января 2012

Удаленная таблица как не на том сервере? Возможно ли, что соединение фактически выполняет несколько вызовов к удаленной таблице, в то время как подзапрос выполняет один запрос на копию данных таблицы, что приводит к меньшему времени ожидания в сети?

...