it-swarm.dev

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

Zobacz to pytanie na stosie przepływu:

Korzystam ze sterownika EasySoft ODBC), aby połączyć wystąpienie SQL Server 2008 R2 Express z Interbase i mam problemy z uzyskaniem metadanych ze zdalnego serwera. Od szukania w sieci głównych sugestii wszyscy wspominają o użyciu OPENQUERY zamiast czteroczęściowej połączonej składni serwera.

NA PRZYKŁAD. 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 OLE DB „MSDASQL” dla połączonego serwera „LBLIVE” dostarczył niespójne metadane. Dostarczono dodatkową kolumnę podczas wykonywania, której nie znaleziono podczas kompilacji czas.

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

Msg 7315, poziom 16, stan 1, wiersz 1 OLE DB dostawca „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.

15
Rich Andrews

Podsumowanie

Pozwól połączonemu serwerowi zrobić jak najwięcej.
Jest niemożliwe dla SQL Server, aby zoptymalizować zapytanie na połączonym serwerze, nawet innym SQL Server

Długo

Kluczowym czynnikiem jest gdzie zapytanie jest uruchamiane.

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 wpływać sp_serveroption . Ustawienie collation compatible mó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: na moim foo = 'bar' Drugi przykład 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.

20
gbn