Welches ist effizienter: Vom Verbindungsserver auswählen oder in den Verbindungsserver einfügen?

32

Angenommen, ich muss Daten von einem Server auf einen anderen exportieren (über Verbindungsserver). Welche Aussage wird effizienter sein?

Ausführung im Quellserver:

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

Oder auf dem Zielserver ausführen:

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

Welcher Server wird schneller sein und insgesamt weniger Ressourcen verbrauchen (Quell- und Zielserver)? Beide Server sind SQL Server 2005.

Guillermo Gutiérrez
quelle

Antworten:

29

Angenommen, ich muss Daten von einem Server auf einen anderen exportieren.

Am besten ist es zu benutzen

  • WENN Sie möchten, dass alle Daten gesichert / wiederhergestellt werden. BCP OUT & BCP IN oder SSIS
  • WENN Sie eine Untergruppe von Daten wünschen (nur einige Tabellen), verwenden Sie SSIS oder BCP OUT & BCP IN

Um Daten je nach Datenmenge / -größe und Bandbreite (n / w) zu verschieben, wird die Leistung durch den Verbindungsserver beeinträchtigt.

Ausführung auf dem Quellserver oder auf dem Zielserver - Welcher Server ist schneller und benötigt insgesamt weniger Ressourcen (sowohl Quell- als auch Zielserver)?

- Ausführung im Quellserver:

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

Dies wird PUSHING-Daten genannt, wenn Sie die Abfrage auf dem Quellserver ausführen und die Daten auf den Zielserver übertragen. Dies wird eine teure Operation sein.

--- wird auf dem Zielserver ausgeführt

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

Dies wird PULLING-Daten genannt, wenn Sie die Abfrage auf dem Zielserver ausführen und Daten vom Quellserver abrufen. Dies ist viel schneller und weniger ressourcenintensiv als das vorherige Verfahren (abhängig davon, wie viele Daten abgerufen werden).

Bei der Pull-Methode mit SQL Profiler sehen Sie, dass eine einzelne SQL-Anweisung über den Verbindungsserver (Quellserver) ausgeführt wird und die Ergebnismenge vom Quellserver auf den Zielserver übertragen wird, was einen enormen Leistungsgewinn gegenüber PUSH darstellt Methode.

Ein weiterer zu beachtender Punkt ist:

Zwischen dem Verbindungsserver (4-teilige Namenskonvention verwendet servername.databasenname.schema.tabellenname aka Verteilte Abfragen) und OPENQUERY ist OPENQUERY im Allgemeinen schnell. Warum ?

Für Verbindungsserver - Der Abfrageoptimierer erstellt einen Ausführungsplan anhand der Abfragenomenklatur und unterteilt ihn in ferne und lokale Abfragen. Lokale Abfragen werden lokal ausgeführt und Daten für Remoteabfragen werden von den Remoteservern gesammelt, lokal gelöscht, kombiniert und dem Endbenutzer als einzelner Datensatz präsentiert.

Für OPENQUERY - Führt die angegebene Pass-Through-Abfrage auf dem angegebenen Verbindungsserver aus. SQL Server sendet Pass-Through-Abfragen als nicht interpretierte Abfragezeichenfolgen an eine OLE DB-Datenquelle. Daher wendet SQL keine Logik auf die Abfrage an und versucht nicht zu schätzen, was diese Abfrage bewirken würde. Sie übergibt die angegebene Abfrage einfach so wie sie ist an den Ziel-Verbindungsserver. Offene Abfragen sind nützlich, wenn Sie nicht mehrere Server in einer Abfrage referenzieren. Es ist im Allgemeinen schnell, da SQL es nicht in mehrere Vorgänge aufteilt und keine lokalen Aktionen für die empfangene Ausgabe ausführt.

Hervorragende Literaturhinweise:

Kin Shah
quelle
8

Wie messen Sie die Effizienz? Welches wird schneller sein? Welches wird weniger Ressourcen auf dem Ziel verbrauchen? an der Quelle? Wie viele Zeilen und welche Datentypen enthalten die Spalten in diesen Zeilen? Sind Sie sicher, dass Sie eine TVF über einen Verbindungsserver ausführen können (ist das Ziel SQL 2008 oder höher?) ? Wie stellen Sie eine 1: 1-Migration dieser Daten sicher, wenn Sie von einem TVF ziehen?

Mit diesen Fragen aus dem Weg ...

Update 1

Es hört sich so an, als würden Sie nach ETL (Extract-Transform-Load) suchen. Ich empfehle SSIS (SQL Server Integration Services), mit dem Sie die Daten aus der Quelle abrufen, die benötigten Transformationen anwenden und diese dann in Ihr Ziel laden können. Das klingt, als wäre es ein ziemlich einfaches Paket (abhängig von den Transformationen).


Herkömmliche Weisheiten besagen, dass der Verbindungsserver-Ansatz die Verbindung beendet, die Daten auf den lokalen Server abruft und dann eine beliebige Logik (Filter, Verknüpfungen usw.) auf den lokalen Server anwendet. Das Abrufen der Daten auf dem Verbindungsserver ist mit einem gewissen Aufwand verbunden, der Großteil der Verarbeitung wird jedoch lokal abgewickelt.

Die OPENQUERY-Methode legt die Verarbeitung auf dem Remote-Server ab und die "gefilterten Ergebnisse" werden vom lokalen Server empfangen.

Selbst wenn Sie eine TVF über einen Verbindungsserver ausführen könnten, würden Sie das Schlimmste aus beiden Welten erleben, wenn Sie remote und lokal verarbeiten (vorausgesetzt, Sie hätten zusätzliche Logik, die auf das Set angewendet werden müsste ).

Abhängig davon, wie Sie sich entscheiden, vorwärts zu gehen, würde ich auch nach OPENQUERYMöglichkeiten suchen , Import- / Exportdaten zu sammeln.

Davon abgesehen ...

Wenn sowohl die Quelle als auch das Ziel unter SQL Server (und das Ziel keine niedrigere Version ist), warum nicht eine Sicherung und Wiederherstellung der Daten durchführen? Dies wäre eine echte Datenmigration. Hier ist ein Code für dich.

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;

In dieser Antwort erfahren Sie, wie Sie Vorlagen in SSMS verwenden.

Swasheck
quelle