Quale è più efficiente: selezionare dal server collegato o inserire nel server collegato?


32

Supponiamo di dover esportare dati da un server a un altro (tramite server collegati). Quale affermazione sarà più efficiente?

Esecuzione nel server di origine:

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

O eseguendo nel server di destinazione:

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

Quale sarà più veloce e consumerà meno risorse in totale (sia il server di origine che quello di destinazione)? Entrambi i server sono SQL Server 2005.

Risposte:


29

Supponiamo che devo esportare dati da un server a un altro.

La cosa migliore è usare

  • Se si desidera che tutti i dati utilizzino Backup / Ripristino; BCP OUT e BCP IN o SSIS
  • Se si desidera un sottoinsieme di dati (solo alcune tabelle) utilizzare SSIS o BCP OUT e BCP IN

Per spostare i dati, a seconda della quantità / dimensione dei dati e della larghezza di banda n / n, il server collegato eliminerà le prestazioni.

Esecuzione nel server di origine o esecuzione nel server di destinazione - Quale sarà più veloce e consumerà meno risorse in totale (sia il server di origine che quello di destinazione)?

- Esecuzione nel server di origine:

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

Questo si chiama PUSHING Data mentre si esegue la query sul server di origine e si inseriscono i dati nel server di destinazione. Sarà un'operazione costosa.

--- in esecuzione nel server di destinazione

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

Questo si chiama PULLING Data mentre si esegue la query sul server di destinazione e si estraggono i dati dal server di origine. Questo sarà molto più veloce e meno dispendioso in termini di risorse rispetto al precedente (a seconda di quanti dati vengono estratti).

Nel caso del metodo pull, usando SQL Profiler vedrai che una singola istruzione SQL viene eseguita attraverso il server collegato (server di origine) e il set di risultati viene trasferito dal server di origine al server di destinazione, il che rappresenta un enorme vantaggio in termini di prestazioni rispetto a PUSH metodo.

Un altro punto da notare è:

Tra il server collegato (convenzione di denominazione in 4 parti utilizzata servername.databasename.schema.tablename aka Distributed Queries) e OPENQUERY, generalmente OPENQUERY sarà veloce. Perché ?

Per il server collegato : Query Optimizer crea un piano di esecuzione osservando la nomenclatura della query e la suddivide in query remote e locali. Le query locali vengono eseguite localmente e i dati per le query remote vengono raccolti dai server remoti, cancellati localmente, combinati insieme e presentati all'utente finale come set di record singolo.

Per OPENQUERY : esegue la query pass-through specificata sul server collegato specificato. SQL Server invia query pass-through come stringhe di query non interpretate a un'origine dati OLE DB. Quindi, SQL non applicherà alcun tipo di logica alla query e non proverà a stimare cosa farebbe quella query, passerebbe semplicemente la query specificata così com'è al server collegato di destinazione. Le query aperte sono utili quando non si fa riferimento a più server in una query. È generalmente veloce poiché SQL non lo suddivide in più operazioni e non esegue alcuna azione locale sull'output ricevuto.

Riferimenti di lettura eccellenti:


8

Come stai misurando l'efficienza? Quale sarà più veloce? Quale consumerà meno risorse sull'obiettivo? sulla fonte? Quante righe e che tipo di tipi di dati sono le colonne in queste righe? Sei sicuro di poter eseguire un TVF attraverso un server collegato (è il target SQL 2008 o successivo?) ? Come assicurate una migrazione 1: 1 di questi dati se state estraendo da un TVF?

Con quelle domande fuori dai piedi ...

Aggiornamento 1

Sembra che tu stia cercando ETL (Estrai-Trasforma-Carica). Consiglierei SSIS (SQL Server Integration Services) con il quale è possibile estrarre i dati dall'origine, applicare le trasformazioni necessarie e quindi caricarle nella destinazione. Sembra che sarebbe un pacchetto piuttosto semplice (a seconda delle trasformazioni).


La saggezza convenzionale afferma che l'approccio del server collegato uscirà dal collegamento, estrarrà i dati al server locale e quindi applicherà qualsiasi logica (filtri, join, ecc.) Sul server locale. C'è un sovraccarico per recuperare i dati sul server collegato, ma la maggior parte dell'elaborazione sarà gestita localmente.

Il metodo OPENQUERY inserirà l'elaborazione sul server remoto e i "risultati filtrati" saranno ricevuti dal server locale.

Sembra che anche se tu potessi eseguire un TVF attraverso un server collegato, otterrai il peggio di entrambi i mondi, elaborando in remoto ed elaborando localmente (supponendo che avessi una logica aggiuntiva da applicare sul set).

A seconda di come decidi di andare avanti, esaminerei anche OPENQUERYcome mezzo per importare / esportare dati in blocco.

Detto questo ...

Se sia l'origine che la destinazione su SQL Server (e la destinazione non è una versione precedente), perché non eseguire un backup e un ripristino dei dati? Questa sarebbe una vera migrazione dei dati. Ecco del codice per te.

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;

È possibile fare riferimento a questa risposta su come utilizzare i modelli in SSMS.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.