Hangisi daha verimli: bağlantılı sunucudan birini seç veya bağlı sunucuya ekle?


32

Verileri bir sunucudan diğerine (bağlı sunucular üzerinden) vermem gerektiğini varsayalım. Hangi ifade daha verimli olacak?

Kaynak sunucuda yürütme:

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

Veya hedef sunucuda yürütme:

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

Hangisi daha hızlı olacak ve toplamda daha az sayıda kaynak tüketecektir (hem kaynak hem de hedef sunucu)? Her iki sunucu da SQL Server 2005'tir.

Yanıtlar:


29

Verileri bir sunucudan diğerine vermem gerektiğini varsayalım.

En iyisi kullanmak

  • Tüm verilerin Yedekleme / Geri Yükleme'yi kullanmasını istiyorsanız; BCP ÇIKIŞI ve BCP GİRİŞİ veya SSIS
  • Veri alt kümesini istiyorsanız (yalnızca bazı tablolar) SSIS veya BCP OUT ve BCP IN kullanın.

Veri taşımak için, veri miktarına / boyutuna ve n / w bant genişliğine bağlı olarak, Linked sunucu performansı düşürür.

Kaynak sunucuda yürütme veya hedef sunucuda yürütme - Hangisi daha hızlı olacak ve toplamda daha az kaynak tüketecek (hem kaynak hem de hedef sunucu)?

- Kaynak sunucuda yürütme:

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

Bu, kaynak sunucudaki sorguyu yürütürken ve verileri hedef sunucuya iterken PUSHING Data olarak adlandırılır. Bu pahalı operasyon olacak.

--- hedef sunucuda yürütme

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

Buna hedef sunucudaki sorguyu uygularken ve kaynak sunucudan veri çekerken PULLING Data adı verilir. Bu, öncekine kıyasla çok daha hızlı ve daha az kaynak yoğun olacaktır (ne kadar veri çekildiğine bağlı olarak).

Çekme yöntemi durumunda, SQL Profiler kullanarak, bağlantılı bir sunucuda (kaynak sunucu) tek bir SQL ifadesinin çalıştırıldığını ve sonuç kümesinin kaynak sunucudan PUSH'ye göre büyük bir performans kazancı olan hedef sunucuya çekildiğini göreceksiniz. yöntem.

Dikkat edilmesi gereken bir başka nokta:

Bağlantılı sunucu (4 bölüm adlandırma kuralı servername.databasename.schema.tablename aka Dağıtılmış Sorgular) ve OPENQUERY arasında, genellikle OPENQUERY hızlı olacaktır. Niye ya ?

Linked Server için - Query optimizer sorgu terminolojisine bakarak bir yürütme planı oluşturur ve uzak ve yerel sorgulara böler. Yerel sorgular yerel olarak yürütülür ve uzak sorgular için veriler uzak sunuculardan toplanır, yerel olarak temizlenir, bir araya getirilir ve son kullanıcıya tek bir kayıt kümesi olarak sunulur.

OPENQUERY için - Belirtilen bağlantılı sunucuda belirtilen doğrudan sorguyu yürütür. SQL Server doğrudan sorguları yorumlanmamış sorgu dizeleri olarak bir OLE DB veri kaynağına gönderir. Bu nedenle, SQL sorguya herhangi bir tür mantık uygulamaz ve bu sorgunun ne yapacağını tahmin etmeye çalışmaz, yalnızca belirtilen sorguyu hedef bağlantılı sunucuya olduğu gibi iletir. Açık sorgular, tek bir sorguda birden fazla sunucuya referans vermediğinizde kullanışlıdır. SQL bunu birden fazla işleme bölmediğinden ve alınan çıktı üzerinde herhangi bir yerel eylem gerçekleştirmediğinden genellikle hızlıdır.

Mükemmel okuma referansları:


8

Verimliliği nasıl ölçüyorsunuz? Hangisi daha hızlı olacak? Hangisi hedefte daha az kaynak tüketir? kaynağında? Bu satırlardaki sütunlar kaç satır ve ne tür veri tipleridir? Eğer bağlantılı bir sunucu üzerinden bir TVF yürütebileceği eminiz (hedef SQL 2008 veya sonrası mi?) ? Bir TVF'den çekiyorsanız, bu verilerin 1: 1 oranında taşınmasını nasıl sağlıyorsunuz?

Bu sorular yoldan çıkınca ...

Güncelleme 1

ETL (Extract-Transform-Load) aradığınızı gibi geliyor. Verileri kaynaktan çekebileceğiniz, ihtiyaç duyduğunuz dönüştürmeleri uygulayabileceğiniz ve daha sonra bunları hedefinize yükleyebileceğiniz SSIS (SQL Server Entegrasyon Servisleri) 'yi öneririm . Bu (dönüşümlere bağlı olarak) oldukça basit bir paket olacak gibi geliyor.


Geleneksel bilgelik, bağlantılı sunucu yaklaşımının bağlantıya gideceğini, verileri yerel sunucuya çekeceğini ve ardından yerel sunucuya herhangi bir mantık (filtreler, birleştirmeler vb.) Uygulayacağını belirtir. Bağlantılı sunucudaki verileri almak için ek yükler vardır, ancak işlemlerin çoğu yerel olarak ele alınacaktır.

AÇMA yöntemi, uzak sunucuya işlemi koyacaktır ve "filtrelenmiş sonuçlar" yerel sunucu tarafından alınacaktır.

Bir TVF'yi bağlı bir sunucu üzerinden yürütebilseniz bile, her iki dünyanın da en kötüsünü, uzaktan işlemeyi ve yerel olarak işlemeyi (sete uygulamak için ek bir mantık olduğunu varsayarak) elde edersiniz.

İlerlemeye nasıl karar verdiğinize bağlı olarak, OPENQUERYveri alma / verme işleminin bir aracı olarak da göz önünde bulundururum .

Hepsini söyledikten sonra ...

Hem kaynak hem de hedef SQL Server'da ise (ve hedef daha düşük sürüm değilse), neden verileri yedeklemiyor ve geri yüklemiyorsunuz? Bu gerçek bir veri göçü olacaktır. İşte size bazı kodlar.

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;

Şablonların SSMS’de nasıl kullanılacağı hakkındaki bu cevaba başvurabilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.