it-swarm.asia

SQL Server Linked Server kinerja: Mengapa permintaan jarak jauh begitu mahal?

Saya memiliki dua server basis data, terhubung melalui Server Tertaut. Keduanya adalah database SQL Server 2008R2, dan koneksi server yang ditautkan dibuat melalui tautan "SQL Server" biasa, menggunakan konteks keamanan login saat ini. Server yang ditautkan keduanya berada di pusat data yang sama, sehingga koneksi tidak menjadi masalah.

Saya menggunakan kueri berikut untuk memeriksa nilai kolom identifier mana yang tersedia dari jarak jauh, tetapi tidak secara lokal.

SELECT 
    identifier 
FROM LinkedServer.RemoteDb.schema.[TableName]

EXCEPT

SELECT DISTINCT
    identifier 
FROM LocalDb.schema.[TableName] 

Di kedua tabel terdapat indeks yang tidak berkerumun di kolom identifier. Secara lokal sekitar 2,6M baris, hanya berjarak 54. Namun, ketika melihat rencana kueri, 70% dari waktu eksekusi dikhususkan untuk "mengeksekusi kueri jarak jauh". Juga, ketika mempelajari rencana kueri lengkap, jumlah baris lokal yang diperkirakan adalah 1 dari pada 2695380 (yang merupakan jumlah taksiran baris saat memilih hanya kueri yang muncul setelah EXCEPT). Execution plan Saat menjalankan kueri ini, memang butuh waktu lama.

Itu membuat saya bertanya-tanya: Mengapa ini? Apakah perkiraan "hanya" jauh, atau apakah pertanyaan jarak jauh pada server yang terhubung benar-benar semahal itu?

15
vstrien

Rencana yang Anda miliki saat ini terlihat seperti rencana paling optimal bagi saya.

Saya tidak setuju dengan pernyataan di jawaban lain bahwa ia mengirim baris 2.6M ke server jarak jauh.

Rencana itu terlihat bagi saya seolah-olah untuk masing-masing 54 baris yang dikembalikan dari permintaan jarak jauh itu melakukan pencarian indeks ke tabel lokal Anda untuk menentukan apakah cocok atau tidak. Ini adalah rencana optimal.

Mengganti dengan hash join atau gabung bergabung akan menjadi kontraproduktif mengingat ukuran tabel dan menambahkan perantara #temp table hanya menambahkan langkah tambahan yang sepertinya tidak memberi Anda keuntungan.

10
Martin Smith

Menghubungkan ke sumber daya jarak jauh mahal. Titik.

Salah satu operasi yang paling mahal di lingkungan pemrograman apa pun adalah jaringan IO (meskipun disk IO cenderung mengerdilkannya)).

Ini meluas ke server yang terhubung jauh. Server yang memanggil server yang terhubung jauh perlu terlebih dahulu membuat koneksi, kemudian permintaan harus dijalankan pada server jauh, hasilnya dikembalikan dan koneksi ditutup. Ini semua membutuhkan waktu melalui jaringan.


Anda juga harus menyusun kueri Anda sedemikian rupa sehingga Anda mentransfer data minimum melalui kawat. Jangan berharap DB akan mengoptimalkan untuk Anda.

Jika saya menulis kueri ini, saya akan memilih data jarak jauh menjadi variabel tabel (atau ke tabel temp) dan kemudian menggunakan ini dalam hubungannya dengan tabel lokal. Ini memastikan bahwa hanya data yang perlu ditransfer yang akan.

Kueri yang Anda jalankan dapat dengan mudah mengirim baris 2,6M ke server jarak jauh untuk memproses klausa EXCEPT.

6
Oded

Saya bukan ahli tetapi jika Anda menggunakan Union, Kecuali, atau Intersect, Anda tidak harus menggunakan "Distinct". Bergantung pada nilai-nilai dari LocalDb.schema. [TableName], kinerja kueri dapat ditingkatkan.

SELECT 
    identifier 
FROM LinkedServer.RemoteDb.schema.[TableName]

EXCEPT

SELECT 
    identifier 
FROM LocalDb.schema.[TableName]
1
joakon

Oded benar, masalah kinerja disebabkan oleh pengiriman baris 2.6M ke server jarak jauh Anda.

Untuk memperbaiki masalah ini, Anda dapat memaksa data jarak jauh (54 baris) dikirim kepada Anda dengan menggunakan temp atau dalam tabel memori.

Menggunakan tabel sementara

SELECT  identifier 
INTO    #TableName
FROM    LinkedServer.RemoteDb.schema.[TableName]

SELECT  identifier
FROM    #TableName
EXCEPT
SELECT  DISTINCT identifier 
FROM    LocalDb.schema.[TableName] 

DROP    #TableName
0

Saya pikir Anda lebih baik mereplikasi tabel jarak jauh ke server tempat Anda bertanya dan kemudian menjalankan semua SQL Anda secara lokal.

0
Alen