Implicaciones de rendimiento del uso de OPENQUERY en una vista

15

Por favor vea esta pregunta en stackoverflow:

Estoy usando un controlador ODBC EasySoft para vincular una instancia de SQL Server 2008 R2 Express a Interbase y tengo algunas dificultades para obtener metadatos del servidor remoto. Al mirar en la red, las principales sugerencias mencionan el uso de OPENQUERY en lugar de la sintaxis del servidor vinculado de cuatro partes.

EG Mi enfoque actual (problemático) es ...

CREATE VIEW [LIVE].[vwPRDETS]
AS

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

Pero en algunas tablas me sale el error al llamar a la vista ...

Mensaje 7353, Nivel 16, Estado 1, Línea 1 El proveedor OLE DB "MSDASQL" para el servidor vinculado "LBLIVE" proporcionó metadatos inconsistentes. Se suministró una columna adicional durante la ejecución que no se encontró en el momento de la compilación.

Además, algunas vistas que ni siquiera puedo crear porque obtengo lo siguiente ...

Mensaje 7315, nivel 16, estado 1, línea 1 El proveedor OLE DB "MSDASQL" para el servidor vinculado "LBLIVE" contiene varias tablas que coinciden con el nombre "" SYSDBA "." AUDIT_LBABKP "".

Aunque solo hay una de las tablas mencionadas.

El enfoque alternativo de buscar en la red parece ser más como ...

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

Entonces, mi pregunta es, si uso OPENQUERY en mi definición de vista, ¿podrá SQL Server optimizar el SQL resultante que se envía a Interbase? ¿O realmente no hay mucha diferencia entre los dos enfoques?

Es un tema cruzado y me encantaría el POV de un dba.

Rich Andrews
fuente

Respuestas:

20

Resumen

Deje que el servidor vinculado haga todo lo posible.
Es imposible para SQL Server optimizar una consulta en un servidor vinculado, incluso otro SQL Server

Largo

El factor clave es donde se ejecuta la consulta.

En este caso, es un SELECCIONAMIENTO trivial, por lo que todas las filas de una tabla se enviarán por el cable. No importa.

Cuando agrega JOINs y WHEREs entonces puede importar. Desea que SQL Server permita que el servidor vinculado realice el mayor filtrado posible para reducir el tamaño de los datos que provienen de la red.

Por ejemplo, el segundo caso aquí debería ser más eficiente.

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

Una limitación de OPENQUERY es que no puede parametrizar: por lo tanto, necesita SQL dinámico para agregar cláusulas WHERE, etc.

El rendimiento de los servidores vinculados puede verse afectado por sp_serveroption. El escenario lo collation compatibledice todo

Si esta opción se establece en verdadera, SQL Server supone que todos los caracteres en el servidor vinculado son compatibles con el servidor local, con respecto al conjunto de caracteres y la secuencia de clasificación (u orden de clasificación). Esto permite que SQL Server envíe comparaciones en columnas de caracteres al proveedor. Si no se establece esta opción, SQL Server siempre evalúa las comparaciones en columnas de caracteres localmente.

Es decir, intente no permitir que SQL Server procese los datos localmente.

Nota: En mi foo = 'bar'segundo ejemplo anterior, el filtro se envía al servidor vinculado porque es solo una cadena constante a SQL Server. La cláusula WHERE real en el primer ejemplo puede o no enviarse de forma remota.

Finalmente, también descubrí que organizar los datos en una tabla temporal y unirlos en tablas locales a menudo es mejor que unirse directamente a OPENQUERY.

gbn
fuente
+1 ¿Por qué mi comparación de la cláusula where simple contra un literal de cadena se ejecuta en el servidor remoto? La respuesta fue "cotejo compatible". Gracias.
mwardm