Implicações de desempenho do uso do OPENQUERY em uma exibição

15

Por favor, veja esta pergunta no stackoverflow:

Estou usando um driver ODBC EasySoft para vincular uma instância do SQL Server 2008 R2 Express à Interbase e estou tendo algumas dificuldades em obter metadados do servidor remoto. Ao olhar na rede, as principais sugestões mencionam o OPENQUERY, em vez da sintaxe do servidor vinculado em quatro partes.

EG Minha abordagem atual (problemática) é ...

CREATE VIEW [LIVE].[vwPRDETS]
AS

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

Mas em algumas tabelas, recebo o erro ao chamar a visualização ...

Mensagem 7353, Nível 16, Estado 1, Linha 1 O provedor OLE DB "MSDASQL" para o servidor vinculado "LBLIVE" forneceu metadados inconsistentes. Uma coluna extra foi fornecida durante a execução que não foi encontrada no tempo de compilação.

Além disso, algumas visualizações que não consigo criar, porque recebo o seguinte ...

Mensagem 7315, Nível 16, Estado 1, Linha 1 O provedor OLE DB "MSDASQL" para o servidor vinculado "LBLIVE" contém várias tabelas que correspondem ao nome "" SYSDBA "." AUDIT_LBABKP "".

Embora exista apenas uma das tabelas mencionadas.

A abordagem alternativa de pesquisar na rede parece ser mais como ...

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

Portanto, minha pergunta é: se eu usar OPENQUERY na minha definição de exibição, o SQL Server poderá otimizar o SQL resultante que está sendo enviado para o Interbase? Ou realmente não há muita diferença entre as duas abordagens?

É um assunto sobre o assunto e adoraria o ponto de vista de um dba.

Rich Andrews
fonte

Respostas:

20

Sumário

Deixe o servidor vinculado fazer o máximo possível.
É impossível para o SQL Server otimizar uma consulta em um servidor vinculado, mesmo em outro SQL Server

Grandes

O fator principal é onde a consulta é executada.

Nesse caso, é um SELECT trivial para que todas as linhas de uma tabela sejam enviadas pelo fio. Não importa.

Quando você adiciona JOINs e WHEREs, isso pode importar. Você deseja que o SQL Server permita que o servidor vinculado faça o máximo de filtragem possível para reduzir o tamanho dos dados provenientes da rede.

Por exemplo, o segundo caso aqui deve ser mais 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 ...

Uma limitação do OPENQUERY é que você não pode parametrizar: portanto, você precisa de SQL dinâmico para adicionar cláusulas WHERE etc.

O desempenho dos servidores vinculados pode ser afetado por sp_serveroption. A configuração collation compatiblediz tudo

Se essa opção estiver configurada como true, o SQL Server assumirá que todos os caracteres no servidor vinculado são compatíveis com o servidor local, com relação ao conjunto de caracteres e sequência de intercalação (ou ordem de classificação). Isso permite que o SQL Server envie comparações nas colunas de caracteres para o provedor. Se essa opção não estiver definida, o SQL Server sempre avaliará comparações localmente em colunas de caracteres.

Ou seja, tente não permitir que o SQL Server processe os dados localmente.

Nota: No meu foo = 'bar'segundo exemplo acima, o filtro é enviado ao servidor vinculado porque é apenas uma constante de cadeia de caracteres para o SQL Server. A cláusula WHERE real no primeiro exemplo pode ou não ser enviada remotamente.

Por fim, também descobri que organizar os dados em uma tabela temporária e associá-los às tabelas locais geralmente é melhor do que ingressar diretamente no OPENQUERY.

gbn
fonte
+1 Por que minha comparação simples da cláusula where contra uma literal de cadeia de caracteres está sendo executada no servidor remoto? A resposta foi "compactação compatível". Obrigado.
mwardm