Який з них більш ефективний: вибрати з пов'язаного сервера або вставити на зв'язаний сервер?


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

Для переміщення даних, залежно від кількості / розміру даних та пропускної здатності n / w, пов'язаний сервер знищить продуктивність.

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

- Виконання на вихідному сервері:

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 під час виконання запиту на цільовому сервері та витягування даних із вихідного сервера. Це буде набагато швидшим та менш ресурсоємним порівняно з попереднім (залежно від того, скільки даних витягується).

У випадку методу витягування, використовуючи SQL Profiler, ви побачите, що один оператор SQL виконується через пов'язаний сервер (вихідний сервер), а набір результатів переноситься з вихідного сервера на цільовий сервер, що є величезним збільшенням продуктивності за PUSH метод.

Ще один момент, який слід зазначити:

Між Пов'язаним сервером (у 4-х частинах іменування використовуваного servername.databasename.schema.tablename aka розподілених запитів) та OPENQUERY, як правило, OPENQUERY буде швидко. Чому?

Для пов'язаного сервера - оптимізатор запитів створює план виконання, переглядаючи номенклатуру запитів і розбиває її на віддалені та локальні запити. Локальні запити виконуються локально, а дані для віддалених запитів збираються з віддалених серверів, обчислюються локально, поєднуються разом і подаються кінцевому користувачеві як єдиний набір записів.

Для OPENQUERY - виконує вказаний запит проходу на вказаному зв'язаному сервері. SQL Server надсилає запити проходження через неінтерпретовані рядки запитів до джерела даних OLE DB. Отже, SQL не застосовуватиме будь-яку логіку до запиту і не намагатиметься оцінити, що буде робити цей запит, він просто передасть вказаний запит таким, яким він є, до цільового пов'язаного сервера. Відкриті запити корисні, коли ви не посилаєтесь на кілька серверів в одному запиті. Це, як правило, швидко, оскільки SQL не розбиває його на кілька операцій і не виконує жодних локальних дій на отриманий вихід.

Відмінні посилання на читання:


8

Як ви вимірюєте ефективність? Який буде швидше? Хто з них буде споживати менше ресурсів у цілі? на джерело? Скільки рядків та типи даних містять стовпці в цих рядках? Ви впевнені, що можете виконати TVF через підключений сервер (це цільовий SQL 2008 чи пізнішої версії?) ? Як ви забезпечуєте міграцію цих даних 1: 1, якщо ви перетягуєтесь із ТВФ?

З цими питаннями не вдається ...

Оновлення 1

Здається, ви шукаєте ETL (Extract-Transform-Load). Я рекомендую SSIS (послуги інтеграції SQL Server), за допомогою яких можна витягувати дані з джерела, застосовувати потрібні перетворення, а потім завантажувати їх у свою ціль. Це здається, що це був би досить простий пакет (залежно від перетворень).


Звичайна мудрість говорить про те, що підключений серверний підхід вийде на посилання, перетягне дані на локальний сервер, а потім застосує будь-яку логіку (фільтри, з'єднання тощо) на локальному сервері. Існує деяка накладні витрати для отримання даних на підключеному сервері, але більшість обробки буде оброблятися локально.

Метод 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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.