Последствия использования OPENQUERY в представлении

15

Пожалуйста, посмотрите этот вопрос на stackoverflow:

Я использую драйвер EasySoft ODBC для связи экземпляра SQL Server 2008 R2 Express с Interbase, и у меня возникают трудности с получением метаданных с удаленного сервера. При поиске в сети все основные предложения упоминают об использовании OPENQUERY вместо синтаксиса четырехкомпонентного связанного сервера.

Например, мой текущий (проблемный) подход ...

CREATE VIEW [LIVE].[vwPRDETS]
AS

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

Но на некоторых таблицах я получаю ошибку при вызове представления ...

Сообщение 7353, уровень 16, состояние 1, строка 1 Поставщик OLE DB "MSDASQL" для связанного сервера "LBLIVE" предоставил несогласованные метаданные. Во время выполнения был предоставлен дополнительный столбец, который не был найден во время компиляции.

Кроме того, некоторые виды я даже не могу создать, потому что получаю следующее ...

Сообщение 7315, уровень 16, состояние 1, строка 1 Поставщик OLE DB "MSDASQL" для связанного сервера "LBLIVE" содержит несколько таблиц, которые соответствуют имени "" SYSDBA "." AUDIT_LBABKP "".

Хотя есть только одна из упомянутых таблиц.

Альтернативный подход от поиска в сети, похоже, больше похож на ...

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

Итак, мой вопрос: если я использую OPENQUERY в своем определении представления, сможет ли SQL Server оптимизировать полученный SQL-запрос, отправляемый в Interbase? Или на самом деле нет большой разницы между этими двумя подходами?

Это пересекающаяся тема, и она хотела бы получить POV от dba.

Рич Эндрюс
источник

Ответы:

20

Резюме

Пусть связанный сервер сделает как можно больше.
Это невозможно для SQL Server , чтобы оптимизировать запрос на связанном сервере, даже другой SQL Server

Длинная

Ключевым фактором является то, где выполняется запрос.

В этом случае это тривиальный SELECT, поэтому все строки таблицы будут отправлены по проводам. Это не важно

Когда вы добавляете JOIN и WHERE, это может иметь значение. Вы хотите, чтобы SQL Server позволял связанному серверу выполнять как можно больше фильтрации, чтобы уменьшить размер данных, поступающих по сети.

Например, второй случай здесь должен быть более эффективным.

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

Ограничением OPENQUERY является невозможность параметризации: вам нужен динамический SQL для добавления предложений WHERE и т. Д.

На производительность связанных серверов может повлиять sp_serveroption. Настройка collation compatibleговорит само за себя

Если для этого параметра установлено значение true, SQL Server предполагает, что все символы на связанном сервере совместимы с локальным сервером с учетом набора символов и последовательности сортировки (или порядка сортировки). Это позволяет SQL Server отправлять сравнения по символьным столбцам поставщику. Если этот параметр не задан, SQL Server всегда оценивает сравнения по символьным столбцам локально.

То есть постарайтесь не позволить SQL Server обрабатывать данные локально.

Примечание. Во foo = 'bar'втором примере, приведенном выше, фильтр отправляется на связанный сервер, поскольку он является строковой константой для SQL Server. Реальное предложение WHERE в первом примере может отправляться или не отправляться удаленно.

Наконец, я также обнаружил, что размещение данных во временной таблице и объединение их с локальными таблицами часто лучше, чем непосредственное объединение с OPENQUERY.

ГБН
источник
+1 Почему не было моего простого сравнения условия where со строковым литералом, выполняемым на удаленном сервере? Ответ был «сопоставление сопоставлений». Благодарю.
mwardm