Mana yang lebih efisien: pilih dari server tertaut atau masukkan ke server tertaut?

32

Misalkan saya harus mengekspor data dari satu server ke server lain (melalui server tertaut). Pernyataan mana yang lebih efisien?

Menjalankan di server sumber:

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

Atau mengeksekusi di server target:

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

Yang mana yang lebih cepat dan mengkonsumsi lebih sedikit sumber daya secara total (baik server sumber maupun target)? Kedua server adalah SQL Server 2005.

Guillermo Gutiérrez
sumber

Jawaban:

29

Misalkan saya harus mengekspor data dari satu server ke yang lain.

Yang terbaik adalah menggunakan

  • JIKA Anda ingin semua data menggunakan Backup / Restore; BCP OUT & BCP IN atau SSIS
  • JIKA Anda ingin subset data (hanya beberapa tabel) gunakan SSIS atau BCP OUT & BCP IN

UNTUK memindahkan data, tergantung pada jumlah / ukuran data dan bandwidth n / w, server Linked akan mematikan kinerjanya.

Menjalankan di server sumber atau mengeksekusi di server target - Yang mana yang akan lebih cepat dan mengkonsumsi lebih sedikit sumber daya secara total (sumber dan server target)?

- Menjalankan di server sumber:

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

Ini disebut PUSHING Data saat Anda menjalankan kueri di server sumber dan mendorong data ke server tujuan. Ini akan menjadi operasi yang mahal.

--- mengeksekusi di server target

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

Ini disebut PULLING Data saat Anda menjalankan kueri di server tujuan dan menarik data dari server sumber. Ini akan jauh lebih cepat dan lebih sedikit sumber daya dibandingkan dengan yang sebelumnya (tergantung pada seberapa banyak data yang ditarik).

Dalam kasus metode tarik, menggunakan SQL Profiler Anda akan melihat bahwa pernyataan SQL tunggal dieksekusi di server tertaut (server sumber), dan resultset ditarik dari server sumber ke server tujuan yang merupakan peningkatan kinerja besar dari PUSH metode.

Poin lain yang perlu diperhatikan adalah:

Antara Linked server (konvensi penamaan 4 bagian menggunakan servername.databasename.schema.tablename alias Kueri Terdistribusi) dan OPENQUERY, umumnya OPENQUERY akan cepat. Mengapa

Untuk Server Tertaut - Pengoptimal kueri membuat rencana eksekusi dengan melihat nomenklatur kueri dan memecahnya menjadi kueri jarak jauh dan lokal. Kueri lokal dieksekusi secara lokal dan data untuk kueri jarak jauh dikumpulkan dari server jarak jauh, digosok secara lokal, digabungkan menjadi satu dan disajikan kepada pengguna akhir sebagai satu set rekaman tunggal.

Untuk OPENQUERY - Menjalankan query pass-through yang ditentukan pada server tertaut yang ditentukan. SQL Server mengirimkan pass-through queries sebagai string kueri yang tidak ditafsirkan ke sumber data OLE DB. Oleh karena itu, SQL tidak akan menerapkan jenis logika apa pun pada kueri dan tidak akan mencoba memperkirakan apa yang akan dilakukan kueri itu, ia hanya akan melewati kueri yang ditentukan seperti halnya ke server target tertaut. Pertanyaan terbuka bermanfaat ketika Anda tidak mereferensikan banyak server dalam satu permintaan. Ini umumnya cepat karena SQL tidak memecahnya menjadi beberapa operasi dan tidak melakukan tindakan lokal pada output yang diterima.

Referensi bacaan yang sangat baik:

Kin Shah
sumber
8

Bagaimana Anda mengukur efisiensi? Yang mana yang lebih cepat? Mana yang akan mengkonsumsi lebih sedikit sumber daya pada target? pada sumbernya? Berapa banyak baris dan tipe data apa yang merupakan kolom dalam baris ini? Apakah Anda yakin dapat menjalankan TVF melalui server yang ditautkan (apakah target SQL 2008 atau yang lebih baru?) ? Bagaimana Anda memastikan migrasi 1: 1 dari data ini jika Anda menarik dari TVF?

Dengan pertanyaan-pertanyaan itu ...

Perbarui 1

Sepertinya Anda sedang mencari ETL (Extract-Transform-Load). Saya akan merekomendasikan SSIS (SQL Server Integration Services) yang dengannya Anda dapat menarik data dari sumber, menerapkan transformasi yang Anda butuhkan, dan kemudian memuatnya ke dalam target Anda. Ini terdengar seperti paket yang cukup mudah (tergantung pada transformasi).


Kearifan konvensional menyatakan bahwa pendekatan server tertaut akan keluar ke tautan, tarik data ke server lokal, dan kemudian menerapkan logika apa pun (filter, bergabung, dll.) Di server lokal. Ada beberapa overhead untuk mengambil data pada server yang ditautkan, tetapi sebagian besar pemrosesan akan ditangani secara lokal.

Metode OPENQUERY akan menempatkan pemrosesan pada server jarak jauh dan "hasil yang difilter" akan diterima oleh server lokal.

Sepertinya bahkan jika Anda bisa mengeksekusi TVF melalui server yang terhubung, Anda akan mendapatkan yang terburuk dari kedua dunia, memproses dari jarak jauh dan memproses secara lokal (dengan asumsi Anda memiliki logika tambahan untuk diterapkan pada set tersebut).

Bergantung pada bagaimana Anda memutuskan untuk bergerak maju, saya juga akan melihat OPENQUERYsebagai alat untuk mengimpor / mengekspor data massal.

Setelah mengatakan semua itu ...

Jika sumber dan target di SQL Server (dan target bukan versi yang lebih rendah), mengapa tidak melakukan pencadangan dan pengembalian data? Ini akan menjadi migrasi data yang benar. Ini beberapa kode untuk Anda.

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;

Anda bisa merujuk ke jawaban ini tentang cara menggunakan templat di SSMS.

swasheck
sumber