Estou curioso para saber qual das opções abaixo seria mais eficiente?
Sempre fui um pouco cauteloso quanto ao uso, IN
porque acredito que o SQL Server transforma o conjunto de resultados em uma grande IF
instrução. Para um grande conjunto de resultados, isso pode resultar em baixo desempenho. Para pequenos conjuntos de resultados, não tenho certeza se é preferível. Para grandes conjuntos de resultados, não EXISTS
seria mais eficiente?
WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
vs.
WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2])
sql-server
sql-server-2005
exists
query-performance
sql-in
Randy Minder
fonte
fonte
select 1 from Base...
em suawhere exists
desde que você realmente não se preocupam com os resultados, basta que uma linha realmente existe.Respostas:
EXISTS
será mais rápido porque, assim que o motor encontrar um acerto, parará de ver, pois a condição se revelou verdadeira.Com
IN
, ele coletará todos os resultados da subconsulta antes do processamento posterior.fonte
A resposta aceita é míope e a pergunta um pouco vaga, pois:
Eu acredito que o otimizador é inteligente o suficiente para converter entre "em" vs "existe" quando há uma diferença de custo significativa devido a (1) e (2), caso contrário, pode ser usado apenas como uma dica (por exemplo, existe para encorajar o uso de um índice procurável no lado direito).
Ambos os formulários podem ser convertidos em formulários de junção internamente, ter a ordem de junção invertida e executar como loop, hash ou mesclagem - com base nas contagens de linhas estimadas (esquerda e direita) e na existência de índice à esquerda, à direita ou em ambos os lados.
fonte
IN
eEXISTS
. Tente encontrar qualquer caso em que eles não obtenham o mesmo plano (embora isso não se aplique aNOT IN
eNOT EXISTS
)Eu fiz alguns testes no SQL Server 2005 e 2008, e tanto no EXISTS quanto no IN voltaram com exatamente o mesmo plano de execução real, como outros declararam. O Otimizador é ótimo. :)
Porém, deve-se estar ciente de que EXISTS, IN e JOIN às vezes podem retornar resultados diferentes se você não formular sua consulta corretamente: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210 .aspx
fonte
Há muitas respostas enganosas aqui, incluindo a altamente votada (embora eu não acredite que suas operações tenham feito mal). A resposta curta é: são iguais.
Existem muitas palavras-chave na linguagem (T-) SQL, mas no final, a única coisa que realmente acontece no hardware são as operações vistas no plano de consulta de execução.
A operação relacional (teoria matemática) que fazemos quando invocamos
[NOT] IN
e[NOT] EXISTS
é a semi join (anti-join ao usarNOT
). Não é uma coincidência que as operações correspondentes do sql-server tenham o mesmo nome . Não há nenhuma operação que mencioneIN
ou emEXISTS
qualquer lugar - apenas (anti) semi-junções. Assim, não há como uma escolha logicamente equivalenteIN
vsEXISTS
afetar o desempenho porque há uma e única maneira, a operação de execução de (anti) semi-junção, de obter seus resultados .Um exemplo:
Consulta 1 ( plano )
Consulta 2 ( plano )
fonte
Eu iria com EXISTS em vez de IN, veja o link abaixo:
SQL Server: JOIN vs IN vs EXISTS - a diferença lógica
Crédito do blog: https://stackoverflow.com/users/31345/mladen-prajdic
fonte
Os planos de execução normalmente serão idênticos nesses casos, mas até que você veja como o otimizador influencia em todos os outros aspectos dos índices etc., você realmente nunca saberá.
fonte
Portanto, IN não é igual a EXISTS nem produzirá o mesmo plano de execução.
Normalmente EXISTS é usado em uma subconsulta correlacionada, o que significa que você irá JUNTAR a consulta interna EXISTS à sua consulta externa. Isso adicionará mais etapas para produzir um resultado, pois você precisa resolver as junções de consulta externa e as junções de consulta interna e, em seguida, corresponder suas cláusulas where para unir ambas.
Normalmente IN é usado sem correlacionar a consulta interna com a consulta externa, e isso pode ser resolvido em apenas uma etapa (na melhor das hipóteses).
Considere isto:
Se você usar IN e o resultado da consulta interna for milhões de linhas de valores distintos, provavelmente terá um desempenho MAIS LENTO do que EXISTS, visto que a consulta EXISTS tem desempenho (tem os índices corretos para se juntar à consulta externa).
Se você usar EXISTS e a junção com sua consulta externa for complexa (leva mais tempo para ser executada, nenhum índice adequado), ela tornará a consulta mais lenta pelo número de linhas na tabela externa; às vezes, o tempo estimado para conclusão pode ser em dias. Se o número de linhas for aceitável para o hardware fornecido ou se a cardinalidade dos dados estiver correta (por exemplo, menos valores DISTINCT em um conjunto de dados grande) IN pode ser executado mais rápido do que EXISTS.
Todos os itens acima serão observados quando você tiver uma quantidade razoável de linhas em cada tabela (por justo, quero dizer algo que excede o processamento da CPU e / ou limites de memória ram para cache).
Portanto, a RESPOSTA é DEPENDE. Você pode escrever uma consulta complexa dentro de IN ou EXISTS, mas como regra geral, você deve tentar usar IN com um conjunto limitado de valores distintos e EXISTS quando você tem muitas linhas com muitos valores distintos.
O truque é limitar o número de linhas a serem verificadas.
Saudações,
MarianoC
fonte
Para otimizar o
EXISTS
, seja muito literal; algo precisa estar lá, mas você não precisa realmente de nenhum dado retornado da subconsulta correlacionada. Você está apenas avaliando uma condição booleana.Assim:
WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
Como a subconsulta correlacionada é
RBAR
, a primeira ocorrência do resultado torna a condição verdadeira e ela não é mais processada.fonte
Em cima da minha cabeça e sem garantia de estar correto: acredito que o segundo será mais rápido neste caso.
IN
entrará em curto-circuito assim que encontrar uma correspondência.fonte