Wpływ na wydajność korzystania z OPENQUERY w widoku

15

Zobacz to pytanie na temat Stackoverflow:

Używam sterownika EasySoft ODBC do połączenia instancji SQL Server 2008 R2 Express z Interbase i mam trudności z uzyskaniem metadanych ze zdalnego serwera. Spoglądając w sieci, wszystkie główne sugestie wspominają użycie OPENQUERY zamiast składni czterech serwerów połączonych.

EG Moje obecne (problematyczne) podejście to ...

CREATE VIEW [LIVE].[vwPRDETS]
AS

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

Ale w niektórych tabelach pojawia się błąd podczas wywoływania widoku ...

Msg 7353, poziom 16, stan 1, wiersz 1 Dostawca OLE DB „MSDASQL” dla połączonego serwera „LBLIVE” dostarczył niespójne metadane. Podczas wykonywania dostarczono dodatkową kolumnę, której nie znaleziono w czasie kompilacji.

Ponadto niektórych widoków, których nie mogę nawet utworzyć, ponieważ otrzymuję następujące ...

Msg 7315, poziom 16, stan 1, wiersz 1 Dostawca OLE DB „MSDASQL” dla połączonego serwera „LBLIVE” zawiera wiele tabel pasujących do nazwy „„ SYSDBA ”.„ AUDIT_LBABKP ””.

Chociaż jest tylko jedna z wymienionych tabel.

Alternatywne podejście do przeszukiwania sieci wydaje się bardziej jak ...

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

Więc moje pytanie brzmi: jeśli użyję OPENQUERY w mojej definicji widoku, czy SQL Server będzie w stanie zoptymalizować wynikowy SQL wysyłany do Interbase? Czy też naprawdę nie ma dużej różnicy między tymi dwoma podejściami?

Jest to temat przekrojowy i chciałby POV dba.

Bogaty Andrews
źródło

Odpowiedzi:

20

streszczenie

Pozwól połączonemu serwerowi zrobić jak najwięcej.
To jest niemożliwe dla SQL Server w celu optymalizacji zapytania na serwer połączony, nawet inny SQL Server

Długo

Kluczowym czynnikiem jest miejsce uruchomienia zapytania.

W tym przypadku jest to trywialny WYBÓR, więc wszystkie wiersze z tabeli zostaną przesłane przewodem. To nie ma znaczenia

Gdy dodasz DOŁĄCZ i GDZIE, może to mieć znaczenie. Chcesz, aby SQL Server zezwalał połączonemu serwerowi na przeprowadzanie możliwie największej filtracji, aby zmniejszyć rozmiar danych przesyłanych przez sieć.

Na przykład drugi przypadek powinien być bardziej wydajny.

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 ...

Ograniczeniem OPENQUERY jest to, że nie można parametryzować: więc potrzebujesz dynamicznego SQL, aby dodać klauzule WHERE itp.

Na wydajność połączonych serwerów może mieć wpływ sp_serveroption. Ustawienie collation compatiblemówi wszystko

Jeśli ta opcja jest ustawiona na wartość true, SQL Server zakłada, że ​​wszystkie znaki na połączonym serwerze są kompatybilne z serwerem lokalnym, w odniesieniu do zestawu znaków i kolejności sortowania (lub kolejności sortowania). Umożliwia to SQL Server wysyłanie porównań kolumn znaków do dostawcy. Jeśli ta opcja nie jest ustawiona, SQL Server zawsze lokalnie ocenia porównania kolumn kolumn.

Oznacza to, że nie pozwól, aby SQL Server przetwarzał dane lokalnie.

Uwaga: W moim foo = 'bar'drugim przykładzie powyżej filtr jest wysyłany do połączonego serwera, ponieważ jest to tylko ciąg znaków do SQL Server. Prawdziwa klauzula WHERE w pierwszym przykładzie może zostać wysłana zdalnie.

Wreszcie odkryłem również, że umieszczanie danych w tabeli tymczasowej i łączenie ich z tabelami lokalnymi jest często lepsze niż łączenie bezpośrednio z OPENQUERY.

gbn
źródło
+1 Dlaczego moje proste porównanie klauzuli where z literałem łańcuchowym nie było wykonywane na zdalnym serwerze? Odpowiedź była „zgodna z sortowaniem”. Dzięki.
mwardm