Desejo saber se tenho uma consulta de junção parecida com esta -
Select E.Id,E.Name from Employee E join Dept D on E.DeptId=D.Id
e uma subconsulta parecida com esta -
Select E.Id,E.Name from Employee Where DeptId in (Select Id from Dept)
Quando considero o desempenho, qual das duas consultas seria mais rápida e por quê ?
Também há um momento em que devo preferir um ao outro?
Desculpe se isso é muito trivial e perguntado antes, mas estou confuso sobre isso. Além disso, seria ótimo se vocês pudessem me sugerir ferramentas que eu deveria usar para medir o desempenho de duas consultas. Muito obrigado!
sql
performance
sql-server-2008
subquery
join
Vishal
fonte
fonte
Respostas:
Eu ESPERO que a primeira consulta seja mais rápida, principalmente porque você tem uma equivalência e um JOIN explícito. Na minha experiência
IN
é um operador muito lento, já que o SQL normalmente o avalia como uma série deWHERE
cláusulas separadas por "OU" (WHERE x=Y OR x=Z OR...
).Porém, como com ALL THINGS SQL, sua milhagem pode variar. A velocidade vai depender muito dos índices (você tem índices nas duas colunas do ID? Isso vai ajudar muito ...) entre outras coisas.
A única maneira REAL de saber com 100% de certeza o que é mais rápido é ativar o rastreamento de desempenho (IO Statistics é especialmente útil) e executar os dois. Certifique-se de limpar seu cache entre as execuções!
fonte
Bem, eu acredito que é uma pergunta "Velha, mas dourada". A resposta é: "Depende!". As performances são um assunto tão delicado que seria bobagem dizer: "Nunca use subconsultas, sempre junte". Nos links a seguir, você encontrará algumas práticas recomendadas básicas que considero muito úteis:
Tenho uma tabela com 50000 elementos, o resultado que procurava era 739 elementos.
Minha pergunta no início foi esta:
e demorou 7,9s para ser executado.
Minha pergunta finalmente é esta:
e demorou 0.0256s
Bom SQL, bom.
fonte
Comece a examinar os planos de execução para ver as diferenças em como o SQl Server os interpretará. Você também pode usar o Profiler para realmente executar as consultas várias vezes e obter a diferença.
Eu não esperaria que eles fossem tão terrivelmente diferentes, onde você pode obter ganhos reais de grande desempenho usando joins em vez de subconsultas quando você usa subconsultas correlacionadas.
EXISTS é geralmente melhor do que qualquer um desses dois e quando você está falando de junções à esquerda onde deseja todos os registros que não estão na tabela de junção à esquerda, então NOT EXISTS é geralmente uma escolha muito melhor.
fonte
O desempenho é baseado na quantidade de dados que você está executando ...
Se for menos dados em torno de 20k. JOIN funciona melhor.
Se os dados forem mais de 100k +, então o IN funciona melhor.
Se você não precisa dos dados da outra tabela, IN é bom, mas é sempre melhor ir para EXISTS.
Todos esses critérios eu testei e as tabelas têm índices adequados.
fonte
O desempenho deve ser o mesmo; é muito mais importante ter os índices e clusters corretos aplicados em suas tabelas (existem alguns bons recursos nesse tópico).
(Editado para refletir a pergunta atualizada)
fonte
As duas consultas podem não ser semanticamente equivalentes. Se um funcionário trabalha para mais de um departamento (possível na empresa para a qual trabalho; isso implicaria que sua tabela não está totalmente normalizada), a primeira consulta retornaria linhas duplicadas, enquanto a segunda não. Para tornar as consultas equivalentes neste caso, a
DISTINCT
palavra - chave teria que ser adicionada àSELECT
cláusula, o que pode ter um impacto no desempenho.Observe que há uma regra de design que estabelece que uma tabela deve modelar uma entidade / classe ou um relacionamento entre entidades / classes, mas não ambos. Portanto, sugiro que você crie uma terceira tabela, digamos
OrgChart
, para modelar o relacionamento entre funcionários e departamentos.fonte
Sei que esse é um post antigo, mas acho que é um tópico muito importante, principalmente hoje em dia onde temos mais de 10 milhões de registros e falamos de terabytes de dados.
Também vou ponderar com as seguintes observações. Tenho cerca de 45 milhões de registros em minha tabela ([dados]) e cerca de 300 registros em minha tabela [gatos]. Tenho uma ampla indexação para todas as consultas sobre as quais estou prestes a falar.
Considere o Exemplo 1:
versus Exemplo 2:
O Exemplo 1 levou cerca de 23 minutos para ser executado. O exemplo 2 demorou cerca de 5 minutos.
Portanto, concluo que a subconsulta neste caso é muito mais rápida. Claro, lembre-se de que estou usando unidades SSD M.2 capazes de i / o @ 1 GB / s (isso é bytes, não bits), então meus índices são muito rápidos também. Portanto, isso pode afetar as velocidades também nas suas circunstâncias
Se for uma limpeza de dados única, provavelmente melhor deixá-la em execução e terminar. Eu uso TOP (10000) e vejo quanto tempo leva e multiplico pelo número de registros antes de atingir a grande consulta.
Se você estiver otimizando bancos de dados de produção, sugiro fortemente o pré-processamento de dados, ou seja, use gatilhos ou corretor de tarefas para atualizar registros assíncronos, de modo que o acesso em tempo real recupere dados estáticos.
fonte
Você pode usar um Plano Explicar para obter uma resposta objetiva.
Para o seu problema, um filtro Exists provavelmente teria o desempenho mais rápido.
fonte