A resposta, como sempre (tudo bem, na maioria das vezes), está no plano de execução.
Existem certos operadores que exigem que todas as linhas cheguem a eles antes de começarem a processar essas linhas e transmiti-las a jusante, por exemplo:
- Hash Join (na construção da tabela de hash)
- Hash Match
- Classificar (exceto fluxo de hash distinto)
Eles são chamados de bloqueio ou param e operam por causa disso, e geralmente são escolhidos quando o otimizador acha que precisará processar muitos dados para encontrá-los.
Existem outros operadores que podem iniciar o streaming ou transmitir qualquer linha encontrada imediatamente
- Loops aninhados
- Associações de mesclagem suportadas por índice
- Agregar agregados
Quando as consultas começam a retornar dados imediatamente, mas não terminam imediatamente, geralmente é um sinal de que o otimizador escolheu um plano para localizar e retornar algumas linhas rapidamente usando operadores que têm um custo inicial mais baixo.
Isso pode acontecer devido às metas de linha introduzidas por você ou pelo otimizador.
Isso também pode acontecer se um plano ruim for escolhido por algum motivo (falta de SARGability, detecção de parâmetros, estatísticas insuficientes etc.), mas isso exige mais escavações para descobrir.
Para mais informações, confira o blog de Rob Farley aqui
E a série de Paul White sobre gols em linha aqui , aqui , aqui e aqui .
Deve-se notar também que, se você estiver falando sobre SSMS, as linhas aparecerão apenas quando um buffer inteiro for preenchido, não apenas por vontade própria.
WHERE t.x IN (<complex SELECT subquery>)
, a LEFT JOIN equivalenteLEFT JOIN (<complex SELECT subquery>) AS r ON r.x = t.x .... WHERE r.x IS NULL
, a subconsulta também precisará ser avaliada (o mesmo plano complexo com o NOT Versão IN).NOT EXISTS
mas o Oracle,NOT IN
em consultas. Mas hoje ele deve ser considerado como erro no gerador de plano