Digamos que eu tenha:
- tabela A muito ampla onde preciso de todas as colunas
- que preciso juntar a uma pequena tabela B que possui MUITAS linhas.
É claro que quando eu uno essas duas tabelas, recebo todo o conteúdo de A para cada linha de B.
Isso está sendo otimizado internamente ou todos esses dados estão sendo enviados pela rede?
Porque se for a última coisa, preciso de muito pouco esforço para juntar manualmente na memória neste caso muito específico.
Exemplo:
SELECT ColumnA1, ColumnA2, ColumnA3, ColumnB1
FROM TableA
JOIN TableB ON TableB.Id = TableA.TableBId
Resultando em dados:
ColumnA1 ColumnA2 ColumnA3 ColumnB1
------------------------------------------------
LargeTextA LargeTextB LargeTextC 1
LargeTextA LargeTextB LargeTextC 2
LargeTextA LargeTextB LargeTextC 3
LargeTextA LargeTextB LargeTextC [1.000.000 times more]
LargeTextA, LargeTextB e LargeTextC serão transmitidos 1.000.000 de vezes na linha ou serão enviados apenas uma vez porque saberá que serão apenas dados repetidos?
Ele repetirá o conteúdo. O SQLServer não tenta adivinhar por que você queria todos esses dados, nem tenta interpolar para reduzir o volume geral enviado.
Se você unir tabelas e sobre chaves parciais (ou seja, não 1:1), obterá esse efeito de multiplicação (ou seja, 1:n) por linha na tabela A.
Se você estiver obtendo muitas linhas de resultados inteiras duplicadas apenas porque o predicado de junção é parcial, então DISTINCT ajudará a reduzir um pouco: por exemplo, rowA1 rowB1 rowA1 rowB1 que se torna apenas rowA1 rowB1 Mas todos os campos precisam ser iguais em ambas as linhas para que isso ocorra.
Eu suspeito que você realmente tem um predicado de junção que lhe dá 1: e não há muito que você possa fazer sobre isso.
Você pode descobrir que o desempenho é melhor retornando um conjunto de linhas inicial que é apenas: rowApk rowBpk
Em seguida, solicitar novamente as linhas específicas na tabela A/tabela B, em vez de tentar consumir um conjunto de linhas grande e inteiro de uma só vez.
Se se tornar um problema de paginação, observe as opções do lado do cliente para colocar o cursor nos dados (em vez de tentar consumir todo o conjunto de resultados) ou coloque os resultados em outro objeto (tabela de trabalho em tempdb, # tabela etc.) e recupere em lotes de lá.
Provavelmente, você deve ver como melhorar as estruturas da tabela para ajudar a agilizar o que você precisa retornar.