Какой из них более эффективен: выбрать со связанного сервера или вставить в связанный сервер?

32

Предположим, мне нужно экспортировать данные с одного сервера на другой (через связанные серверы). Какое утверждение будет более эффективным?

Выполнение на исходном сервере:

INSERT INTO [DestinationLinkedServer].[DestinationDB].[dbo].[Table]
SELECT a, b, c, ... FROM [dbo].Udf_GetExportData()

Или выполнить на целевом сервере:

INSERT INTO [dbo].[Table]
SELECT a, b, c, ...
FROM OPENQUERY([OriginLinkedServer],
    'SELECT a, b, c, ... FROM [OriginDB].[dbo].Udf_GetExportData()')

Какой из них будет быстрее и потреблять меньше ресурсов (как исходного, так и целевого сервера)? Оба сервера являются SQL Server 2005.

Гильермо Гутьеррес
источник

Ответы:

29

Предположим, мне нужно экспортировать данные с одного сервера на другой.

Лучше всего использовать

  • Если вы хотите, чтобы все данные использовались для резервного копирования / восстановления; BCP OUT & BCP IN или SSIS
  • Если вам нужно подмножество данных (только некоторые таблицы), используйте SSIS или BCP OUT & BCP IN

Чтобы переместить данные, в зависимости от объема / размера данных и н / ж пропускной способности, связанный сервер будет снижать производительность.

Выполнение на исходном сервере или выполнение на целевом сервере. Какой из них будет быстрее и потреблять в целом меньше ресурсов (как исходного, так и целевого сервера)?

- Выполнение на исходном сервере:

INSERT INTO [DestinationLinkedServer].[DestinationDB].[dbo].[Table]
SELECT a, b, c, ... FROM [dbo].Udf_GetExportData()

Это называется PUSHING Data, когда вы выполняете запрос на исходном сервере и отправляете данные на конечный сервер. Это будет дорогая операция.

--- выполнение на целевом сервере

INSERT INTO [dbo].[Table]
SELECT a, b, c, ...
FROM OPENQUERY([OriginLinkedServer],
    'SELECT a, b, c, ... FROM [OriginDB].[dbo].Udf_GetExportData()')

Это называется PULLING Data, когда вы выполняете запрос на конечном сервере и извлекаете данные с исходного сервера. Это будет намного быстрее и менее ресурсоемким по сравнению с предыдущим (в зависимости от того, сколько данных извлекается).

В случае метода pull, используя SQL Profiler, вы увидите, что один оператор SQL выполняется на связанном сервере (исходном сервере), а набор результатов переносится с исходного сервера на конечный сервер, что значительно увеличивает производительность по сравнению с PUSH. метод.

Еще один момент, который следует отметить:

Между Связанным сервером (используется соглашение об именовании из 4 частей, имя_сервера.databasename.schema.tablename aka Distributed Queries) и OPENQUERY, обычно OPENQUERY будет быстрым. Зачем ?

Для связанного сервера - оптимизатор запросов создает план выполнения, просматривая номенклатуру запросов и разбивая ее на удаленные и локальные запросы. Локальные запросы выполняются локально, а данные для удаленных запросов собираются с удаленных серверов, локально очищаются, объединяются и представляются конечному пользователю в виде единого набора записей.

Для OPENQUERY - выполняет указанный сквозной запрос на указанном связанном сервере. SQL Server отправляет сквозные запросы в виде не интерпретированных строк запроса в источник данных OLE DB. Следовательно, SQL не будет применять какую-либо логику к запросу и не будет пытаться оценить, что будет делать этот запрос, он просто передаст указанный запрос в том виде, как он есть, на целевой связанный сервер. Открытые запросы полезны, когда вы не ссылаетесь на несколько серверов в одном запросе. Обычно это происходит быстро, так как SQL не разбивает его на несколько операций и не выполняет никаких локальных действий с полученным выводом.

Отличное чтение ссылок:

Кин Шах
источник
8

Как вы измеряете эффективность? Какой из них будет быстрее? Какой из них будет потреблять меньше ресурсов на цели? на источнике? Сколько строк и какие типы данных имеют столбцы в этих строках? Вы уверены, что можете выполнить TVF через связанный сервер (целевой SQL 2008 или более поздний?) ? Как вы обеспечиваете миграцию этих данных 1: 1, если вы извлекаете данные из TVF?

С этими вопросами в сторону ...

Обновление 1

Похоже, вы ищете ETL (Extract-Transform-Load). Я бы порекомендовал SSIS (SQL Server Integration Services), с помощью которого вы можете извлекать данные из источника, применять необходимые преобразования, а затем загружать их в свою цель. Похоже, это будет довольно простой пакет (в зависимости от преобразований).


Традиционно считается, что подход с использованием связанного сервера приведет к соединению, доставит данные на локальный сервер и затем применяет любую логику (фильтры, объединения и т. Д.) На локальном сервере. Есть некоторые издержки при получении данных на связанном сервере, но большая часть обработки будет обрабатываться локально.

Метод OPENQUERY поместит обработку на удаленный сервер, и «отфильтрованные результаты» будут получены локальным сервером.

Кажется, что даже если бы вы могли выполнить TVF через связанный сервер, вы бы получили худшее из обоих миров, обрабатывая удаленно и обрабатывая локально (при условии, что у вас есть дополнительная логика для применения на множестве).

В зависимости от того, как вы решите двигаться вперед, я также рассмотрю в OPENQUERYкачестве средства массового импорта / экспорта данных.

Сказав все это ...

Если и источник, и цель на SQL Server (и цель не является более низкой версией), почему бы не выполнить резервное копирование и восстановление данных? Это будет настоящая миграция данных. Вот код для вас.

BACKUP DATABASE <DatabaseName, sysname, DatabaseName>
TO DISK=N'<backup_location, varchar, BackupLocation>.bak'
WITH INIT, FORMAT, COMPRESSION, COPY_ONLY

RESTORE DATABASE <NewDatabaseName, sysname, NewDatabaseName>
FROM DISK = N'<backup_location, varchar, BackupLocation>\
    <DatabaseName, sysname, DatabaseName>.bak'
WITH 
    MOVE '<DataFileName, sysname, DataFileName>' TO '<DataMDFPath, nvarchar(600), DataMDFPath>',
    MOVE '<LogFilePath, sysname, LogFilePath>' TO '<LogLDFPath, nvarchar(600), LogLDFPath>',
    REPLACE;

Вы можете обратиться к этому ответу о том, как использовать шаблоны в SSMS.

swasheck
источник