Pergunta

Estou curioso para saber qual das seguintes opções abaixo seria mais eficiente?

Eu sempre fui um pouco cauteloso em usar IN Porque acredito que o servidor SQL transforma o resultado em um grande IF declaração. Para um grande conjunto de resultados, isso pode resultar em mau desempenho. Para pequenos conjuntos de resultados, não tenho certeza se é preferível. Para grandes conjuntos de resultados, não seria EXISTS ser 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])
Foi útil?

Solução

EXISTS Será mais rápido porque, uma vez que o motor tenha um acerto, ele parará de parecer que a condição se mostrou verdadeira.

Com IN, ele coletará todos os resultados do sub-quadro antes de processamento adicional.

Outras dicas

A resposta aceita é míope e a pergunta um pouco solta nisso:

1) Nem mencionam explicitamente se um índice de cobertura está presente na esquerda, à direita ou nos dois lados.

2) Nem leva em consideração o tamanho do conjunto do lado esquerdo de entrada e o conjunto do lado direito de entrada.
(A pergunta apenas menciona um grande grande resultado definir).

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 incentivar o uso do uso de um índice A busca no lado direito).

Ambas as formas podem ser convertidas para unir formulários internamente, ter a ordem de junção revertida e executar como loop, hash ou mesclagem nas contagens estimadas de linha (esquerda e direita) e existência de índice na esquerda, à direita, ou nos dois lados.

Fiz alguns testes no SQL Server 2005 e 2008 e, em ambos os existentes, e o In Volt Back com exatamente o mesmo plano de execução real, como outros declararam. O otimizador é ideal. :)

Algo a estar ciente, porém, existe, e a participação, às vezes, pode retornar resultados diferentes se você não formar sua consulta exatamente: http://weblogs.sqtteam.com/mladenp/archive/2007/05/18/60210.aspx

Eu iria existir, veja abaixo o link:

Servidor SQL: JONE VS EM VS Existe - a diferença lógica

Os planos de execução normalmente serão idênticos nesses casos, mas até você ver como os fatores de otimizador em todos os outros aspectos dos índices etc., você realmente nunca saberá.

Portanto, não é o mesmo que existe nem produzirá o mesmo plano de execução.

Geralmente existe é usado em uma subconsulta correlacionada, o que significa que você se juntará à consulta interna existe com sua consulta externa. Isso adicionará mais etapas para produzir um resultado, pois você precisa resolver as junções da consulta externa e a consulta interna se junta e depois combine o local onde as cláusulas se juntam a ambos.

Geralmente, é 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:

  1. Se você usar e o resultado da consulta interna são milhões de linhas de valores distintos, ele provavelmente terá um desempenho mais lento que existe, uma vez que a consulta existe é performante (possui os índices certos para se unir à consulta externa).

  2. Se você usar, existe e a junta -se à sua consulta externa é complexa (leva mais tempo para executar, sem índices adequados), ela retarda a consulta pelo número de linhas na tabela externa, às vezes o tempo estimado a ser concluído pode ser em dias. Se o número de linhas for aceitável para o seu hardware fornecido ou a cardinalidade dos dados estiver correta (por exemplo, menos valores distintos em um grande conjunto de dados), poderão executar mais rápido que existe.

  3. Todos os itens acima serão observados quando você tiver uma quantidade razoável de linhas em cada tabela (de acordo com a feira, quero dizer algo que exceda o processamento da CPU e/ou os limiares de RAM para cache).

Portanto, a resposta é que depende. Você pode escrever uma consulta complexa dentro ou existe, mas, como regra geral, tente usar com um conjunto limitado de valores distintos e existe quando tiver muitas linhas com muitos valores distintos.

O truque é limitar o número de linhas a serem digitalizadas.

Cumprimentos,

Marianoc

Para otimizar o EXISTS, seja muito literal; Algo só tem que estar lá, mas você não precisa de dados retornados do sub-quadro correlacionado. Você está apenas avaliando uma condição booleana.

Então:

WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

Porque o sub-quadro correlacionado é RBAR, o primeiro resultado acerto torna a condição verdadeira e não é processada mais.

Existem muitas respostas enganosas aqui, incluindo a altamente vota (embora eu não acredite que o OPS deles significasse danos). A resposta curta é: estes são iguais.

Existem muitas palavras-chave no idioma (T-) SQL, mas no final, a única coisa que realmente acontece no hardware são as operações, como visto no plano de consulta de execução.

A operação relacional (teoria da matemática) que fazemos quando invocamos [NOT] IN e [NOT] EXISTS é a junção semi (anti-joa ao usar NOT). Não é por acaso que as operações correspondentes do SQL-Server têm o mesmo nome. Não há operação que menciona IN ou EXISTS Em qualquer lugar - apenas (anti -) semi junções. Desta forma, Não há como um logicamente equivalente IN vs. EXISTS A escolha pode afetar o desempenho porque existe uma e única maneira, a (anti) operação de execução semi -junção, para obter seus resultados.

Um exemplo:

Consulta 1 ( plano )

select * from dt where dt.customer in (select c.code from customer c where c.active=0)

Query 2 ( plano )

select * from dt where exists (select 1 from customer c where c.code=dt.customer and c.active=0)

No topo da minha cabeça e não garantido para estar correto: acredito que o segundo será mais rápido neste caso.

  1. No primeiro, a subconsulta correlacionada provavelmente fará com que a subconsulta seja executada para cada linha.
  2. No segundo exemplo, a subconsulta deve ser executada apenas uma vez, uma vez que não está correlacionada.
  3. No segundo exemplo, o IN irá curto-circuito assim que encontrar uma correspondência.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top