Quando executo esta consulta em um servidor SQL Server 2022 com uma conexão de servidor vinculada ao PostgreSQL:
SELECT TOP 1 *
FROM PGSTACK.stackoverflow.[public].users
WHERE Id = 1;
O SQL Server busca todo o conteúdo da tabela de usuários remotos – todas as linhas – pela rede e filtra tudo localmente. A consulta leva >3 minutos para ser executada.
O plano de consulta real não mostra um filtro local – isso implica que o SQL Server está obtendo apenas 1 linha do servidor remoto:
- Pergunta 1: Isso (obter todo o conteúdo da tabela remota) pode ser evitado sem reescrever a consulta para usar OPENQUERY?
- Pergunta 2: Mesmo apenas tentar obter o plano de execução estimado, na verdade, busca todas as linhas da tabela remota e leva> 3 minutos apenas para obter o plano estimado. Isso pode ser evitado?
Detalhes técnicos adicionais:
- O servidor remoto possui uma chave primária no id e a consulta é executada em milissegundos no Postgres
- O pg_stat_activity do servidor Postgres remoto mostra que o SQL Server está executando esta consulta:
select * from "stackoverflow"."public"."users"
- observe a falta de qualquer filtro na tabela - Driver Postgres ODBC 16.00 2023/09/16, versão mais recente aqui
- SQL Server 2022 compilação 16.0.4095.4
- O painel de controle da rede mostra até mesmo a taxa de transferência disparando assim que a consulta é iniciada - e, novamente, estou puxando apenas uma linha aqui:
Você definiu "Use Declare/Fetch" como true nas opções do driver odbc? Da documentação "Se for verdade, o driver usa automaticamente declarar cursor/fetch para manipular instruções SELECT e mantém 100 linhas em um cache. Isso é principalmente uma grande vantagem, especialmente se você estiver interessado apenas em ler e não em atualizar. Isso resulta no driver não está sugando muita memória para armazenar em buffer todo o conjunto de resultados. Se definido como falso, os cursores não serão usados e o driver recuperará todo o conjunto de resultados."
https://odbc.postgresql.org/docs/config.html
Acho que o problema é em relação à
TOP
palavra-chave... O SQL Server não conhece a palavra-chave equivalente no PostgreSQL (LIMIT
), então ele busca todo o conteúdo da tabela, e depois disso, aplica qualquer filtro e palavras-chave reservadas do seu lado... pode você tenta reescrever a instrução select com aWITH
cláusula a ser testada?Algo assim
Não tenho nenhuma VM com PG e SQL para testar, mas é a primeira coisa que me vem à cabeça
Depois de ter flashbacks das visualizações de Brent nos servidores vinculados e perguntar se o aplicativo poderia abrir uma conexão diretamente com o Postgres. Eu criaria um procedimento armazenado, moveria a consulta para o procedimento armazenado no servidor Postgres e chamaria o procedimento.
com o uso do openquery você pode escrever SQL muito mais complexos incluindo joins e ainda ter o desempenho dos índices no outro banco de dados.