Производительность запроса между базами данных (между связанными серверами)

У меня есть импорт между двумя связанными серверами. По сути, мне нужно получить данные из множественного соединения в таблицу на моей стороне.

Текущий запрос выглядит примерно так:

 select a.*
 from db1.dbo.tbl1 a
      inner join db1.dbo.tbl2 on ...
      inner join db1.dbo.tbl3 on ...
      inner join db1.dbo.tbl4 on ...
      inner join db2.dbo.myside on ...

db1 = связанный сервер

db2 = моя собственная база данных

После этого я использую вставку в + select, чтобы добавить эти данные в мою таблицу, которая находится в db2. (обычно несколько сотен записей - этот импорт выполняется раз в минуту)

Мой вопрос связан с производительностью. Таблицы на связанном сервере (tbl1, tbl2, tbl3, tbl4) — это огромные таблицы с миллионами записей, что замедляет процесс импорта. Мне сказали, что если я выполняю соединение на «другой» стороне (db1 — связанный сервер), например, в хранимой процедуре, даже если запрос выглядит так же, он будет выполняться быстрее. Это правильно? Это как-то сложно проверить. Обратите внимание, что соединение также содержит таблицу из моей базы данных.

Также. есть ли другие «трюки», которые я мог бы использовать, чтобы сделать это быстрее? Спасибо


person Ash    schedule 26.05.2010    source источник


Ответы (3)


Правильно размещать хранимую процедуру на db1 для повышения производительности, таким образом меньше данных должно передаваться по каналу, так как многие фильтруются в соединениях.

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

person Snake    schedule 26.05.2010

Это действительно зависит от того, что на самом деле делает ваш запрос. Вы можете использовать подсказку «удаленный» для соединений, чтобы принудительно выполнить соединение на связанном сервере. то есть:

select a.*  
 from db1.dbo.tbl1 a   
      inner remote join db1.dbo.tbl2 on ...  
      inner remote join db1.dbo.tbl3 on ...  
      inner remote join db1.dbo.tbl4 on ...  
      inner join db2.dbo.myside on ... 

(Я предполагаю, что вы исключили сервер из приведенного выше и что все ссылки «db1.» на самом деле являются «linkedserver.db1».)

Если вы можете выполнять большую часть работы только с информацией на связанном сервере, вы можете использовать OPENQUERY для ускорения работы. то есть:

select a.*  
 from OPENQUERY(db1, 'SELECT a.* from db1.dbo.tbl1 a   
      inner join db1.dbo.tbl2 on ...  
      inner join db1.dbo.tbl3 on ...  
      inner join db1.dbo.tbl4 on ... ') a  
      inner join db2.dbo.myside on ... 

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

person Michael    schedule 28.05.2010

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

Чтобы повысить производительность соединения, убедитесь, что у вас есть индексы.

Обратите внимание, что межсерверные вставки опасны, поскольку вы полагаетесь на сеть. Я также не уверен, можно ли использовать транзакции в этом сценарии. Если нет, то это другая проблема.

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

person Community    schedule 26.05.2010