Implikasi kinerja menggunakan OPENQUERY dalam suatu tampilan

15

Silakan lihat pertanyaan ini di stackoverflow:

Saya menggunakan driver EasySoft ODBC untuk menautkan contoh SQL Server 2008 R2 Express ke Interbase dan saya mengalami beberapa kesulitan dengan mendapatkan metadata dari server jauh. Dari mencari di internet sugestions utama semua menyebutkan menggunakan OPENQUERY bukan sintaks server empat bagian yang terhubung.

EG Pendekatan saya saat ini (bermasalah) adalah ...

CREATE VIEW [LIVE].[vwPRDETS]
AS

SELECT *
FROM [LBLIVE]...[PRDETS] WITH (NOLOCK)

Tetapi pada beberapa tabel saya mendapatkan kesalahan saat memanggil tampilan ...

Msg 7353, Level 16, State 1, Line 1 Penyedia OLE DB "MSDASQL" untuk server tertaut "LBLIVE" menyediakan metadata yang tidak konsisten. Kolom tambahan disediakan selama eksekusi yang tidak ditemukan pada waktu kompilasi.

Juga, beberapa tampilan yang bahkan tidak dapat saya buat karena saya mendapatkan yang berikut ...

Msg 7315, Level 16, State 1, Line 1 Penyedia OLE DB "MSDASQL" untuk server tertaut "LBLIVE" berisi beberapa tabel yang cocok dengan nama "" SYSDBA "." AUDIT_LBABKP "".

Meskipun hanya ada satu tabel yang disebutkan.

Pendekatan alternatif dari pencarian di internet tampaknya lebih seperti ...

SELECT *
FROM OPENQUERY(<linked sevrer>, 'SELECT <column list> FROM MyTable')

Jadi, pertanyaan saya adalah, jika saya menggunakan OPENQUERY dalam definisi saya, apakah SQL Server dapat mengoptimalkan SQL yang dihasilkan yang dikirim ke Interbase? Atau apakah benar-benar tidak banyak perbedaan antara kedua pendekatan tersebut?

Ini adalah subjek lintas dan akan menyukai POV dba.

Andrews kaya
sumber

Jawaban:

20

Ringkasan

Biarkan server yang terhubung melakukan sebanyak mungkin.
Hal ini tidak mungkin untuk SQL Server untuk mengoptimalkan query pada server yang terhubung, bahkan lain SQL Server

Panjang

Faktor kuncinya adalah di mana kueri berjalan.

Dalam hal ini, ini adalah SELECT sepele sehingga semua baris dari tabel akan dikirim ke kawat. Itu tidak masalah.

Ketika Anda menambahkan GABUNG dan DI MANA maka itu bisa berarti. Anda ingin SQL Server mengizinkan server yang terhubung untuk melakukan sebanyak mungkin penyaringan untuk mengurangi ukuran data yang datang melalui jaringan.

Sebagai contoh, kasus ke-2 di sini harus lebih efisien.

SELECT *
FROM OPENQUERY(<linked server>, 
            'SELECT <column list> FROM MyTable') T1
     JOIN
     SomeLocalTable T2 ON ...
WHERE T1.foo = 'bar'

SELECT *
FROM OPENQUERY(<linked server>, 
           'SELECT <column list> FROM MyTable WHERE foo = ''bar''')
     JOIN
     SomeLocalTable T2 ON ...

Batasan OPENQUERY adalah bahwa Anda tidak dapat menentukan: jadi Anda perlu SQL dinamis untuk menambahkan klausa WHERE dll.

Kinerja server yang ditautkan dapat dipengaruhi oleh sp_serveroption. Pengaturan collation compatiblemengatakan semuanya

Jika opsi ini disetel ke true, SQL Server mengasumsikan bahwa semua karakter di server yang ditautkan kompatibel dengan server lokal, terkait dengan rangkaian karakter dan urutan susunan (atau susunan urutan). Ini memungkinkan SQL Server untuk mengirim perbandingan pada kolom karakter ke penyedia. Jika opsi ini tidak disetel, SQL Server selalu mengevaluasi perbandingan pada kolom karakter secara lokal.

Artinya, cobalah untuk tidak membiarkan SQL Server memproses data secara lokal.

Catatan: Pada foo = 'bar'contoh ke - 2 saya di atas, filter dikirim ke server tertaut karena hanya berupa string konstan ke SQL Server. Klausa WHERE yang sebenarnya dalam contoh pertama mungkin dikirim atau tidak.

Akhirnya, saya juga menemukan bahwa pementasan data ke tabel temp dan menggabungkannya ke tabel lokal seringkali lebih baik daripada bergabung langsung ke OPENQUERY.

gbn
sumber
+1 Mengapa perbandingan klausa sederhana saya dengan string literal tidak dijalankan di server jauh? Jawabannya adalah "kompatibel dengan susunan". Terima kasih.
mwardm