Respostas:
A exists
palavra-chave pode ser usada dessa maneira, mas na verdade pretende ser uma maneira de evitar a contagem:
--this statement needs to check the entire table
select count(*) from [table] where ...
--this statement is true as soon as one match is found
exists ( select * from [table] where ... )
Isso é mais útil quando você possui if
instruções condicionais, pois exists
pode ser muito mais rápido que count
.
O in
é melhor usado onde você tem uma lista estática para passar:
select * from [table]
where [field] in (1, 2, 3)
Quando você tem uma tabela em uma in
declaração, faz mais sentido usar a join
, mas principalmente isso não deve importar. O otimizador de consulta deve retornar o mesmo plano de qualquer maneira. Em algumas implementações (principalmente mais antigas, como o Microsoft SQL Server 2000), as in
consultas sempre recebem um plano de junção aninhada , enquanto as join
consultas usam aninhado, mesclagem ou hash, conforme apropriado. Implementações mais modernas são mais inteligentes e podem ajustar o plano mesmo quando in
usado.
select * from [table] where [field] in (select [field] from [table2])
retorna os mesmos resultados (e plano de consulta) que select * from [table] join [table2] on [table2].[field] = [table].[field]
.
table
, enquanto a segunda retorna tudo de table
e table2
. Em alguns bancos de dados SQL (principalmente antigos), a in
consulta será implementada como uma junção aninhada, enquanto a join
consulta pode ser aninhada, mesclada, hash etc. - o que for mais rápido.
exists
pode ser usado em uma instrução caso, para que eles possam ser útil dessa forma também ieselect case when exists (select 1 from emp where salary > 1000) then 1 else 0 end as sal_over_1000
EXISTS
informará se uma consulta retornou algum resultado. por exemplo:
SELECT *
FROM Orders o
WHERE EXISTS (
SELECT *
FROM Products p
WHERE p.ProductNumber = o.ProductNumber)
IN
é usado para comparar um valor a vários e pode usar valores literais, como este:
SELECT *
FROM Orders
WHERE ProductNumber IN (1, 10, 100)
Você também pode usar os resultados da consulta com a IN
cláusula, assim:
SELECT *
FROM Orders
WHERE ProductNumber IN (
SELECT ProductNumber
FROM Products
WHERE ProductInventoryQuantity > 0)
Com base no otimizador de regras :
EXISTS
é muito mais rápido do que IN
quando os resultados da subconsulta são muito grandes.IN
é mais rápido que EXISTS
, quando os resultados da subconsulta são muito pequenos.Com base no otimizador de custos :
Suponho que você saiba o que eles fazem e, portanto, sejam usados de maneira diferente; portanto, entenderei sua pergunta como: Quando seria uma boa idéia reescrever o SQL para usar IN em vez de EXISTS ou vice-versa.
Essa é uma suposição justa?
Edit : O motivo pelo qual estou perguntando é que, em muitos casos, você pode reescrever um SQL com base em IN para usar EXISTS e vice-versa, e para alguns mecanismos de banco de dados, o otimizador de consultas tratará os dois de maneira diferente.
Por exemplo:
SELECT *
FROM Customers
WHERE EXISTS (
SELECT *
FROM Orders
WHERE Orders.CustomerID = Customers.ID
)
pode ser reescrito para:
SELECT *
FROM Customers
WHERE ID IN (
SELECT CustomerID
FROM Orders
)
ou com uma junção:
SELECT Customers.*
FROM Customers
INNER JOIN Orders ON Customers.ID = Orders.CustomerID
Portanto, minha pergunta ainda permanece: o pôster original se perguntando o que IN e EXISTS faz e, portanto, como usá-lo, ou ele pergunta se reescrever um SQL usando IN para usar EXISTS, ou vice-versa, será uma boa idéia?
JOIN
, você precisará de umDISTINCT
EXISTS
é muito mais rápido do que IN
quando os resultados da subconsulta são muito grandes.
IN
é mais rápido do que EXISTS
quando os resultados da subconsulta são muito pequenos.
CREATE TABLE t1 (id INT, title VARCHAR(20), someIntCol INT)
GO
CREATE TABLE t2 (id INT, t1Id INT, someData VARCHAR(20))
GO
INSERT INTO t1
SELECT 1, 'title 1', 5 UNION ALL
SELECT 2, 'title 2', 5 UNION ALL
SELECT 3, 'title 3', 5 UNION ALL
SELECT 4, 'title 4', 5 UNION ALL
SELECT null, 'title 5', 5 UNION ALL
SELECT null, 'title 6', 5
INSERT INTO t2
SELECT 1, 1, 'data 1' UNION ALL
SELECT 2, 1, 'data 2' UNION ALL
SELECT 3, 2, 'data 3' UNION ALL
SELECT 4, 3, 'data 4' UNION ALL
SELECT 5, 3, 'data 5' UNION ALL
SELECT 6, 3, 'data 6' UNION ALL
SELECT 7, 4, 'data 7' UNION ALL
SELECT 8, null, 'data 8' UNION ALL
SELECT 9, 6, 'data 9' UNION ALL
SELECT 10, 6, 'data 10' UNION ALL
SELECT 11, 8, 'data 11'
Consulta 1
SELECT
FROM t1
WHERE not EXISTS (SELECT * FROM t2 WHERE t1.id = t2.t1id)
Consulta 2
SELECT t1.*
FROM t1
WHERE t1.id not in (SELECT t2.t1id FROM t2 )
Se no t1
seu ID tiver valor nulo, a Consulta 1 os encontrará, mas a Consulta 2 não poderá encontrar parâmetros nulos.
Quero dizer, IN
não é possível comparar nada com nulo, portanto, não há resultado para nulo, mas EXISTS
pode comparar tudo com nulo.
Se você estiver usando o IN
operador, o mecanismo SQL verificará todos os registros buscados na consulta interna. Por outro lado, se estivermos usando EXISTS
, o mecanismo SQL interromperá o processo de verificação assim que encontrar uma correspondência.
O IN suporta apenas relações de igualdade (ou desigualdade quando precedido por NOT ).
É sinônimo de = any / = some , por exemplo
select *
from t1
where x in (select x from t2)
;
EXISTS suporta tipos variantes de relações, que não podem ser expressas usando IN , por exemplo:
select *
from t1
where exists (select null
from t2
where t2.x=t1.x
and t2.y>t1.y
and t2.z like '℅' || t1.z || '℅'
)
;
As supostas diferenças de desempenho e técnicas entre EXISTS e IN podem resultar de implementações / limitações / bugs de fornecedores específicos, mas muitas vezes eles não passam de mitos criados devido à falta de entendimento interno dos bancos de dados.
A definição das tabelas, a precisão das estatísticas, a configuração do banco de dados e a versão do otimizador têm impacto no plano de execução e, portanto, nas métricas de desempenho.
A Exists
palavra-chave avalia true ou false, mas a IN
palavra-chave compara todo o valor na coluna correspondente da subconsulta. Outro Select 1
pode ser usado com o Exists
comando Exemplo:
SELECT * FROM Temp1 where exists(select 1 from Temp2 where conditions...)
Mas IN
é menos eficiente e Exists
mais rápido.
Eu acho que,
EXISTS
é quando você precisa combinar os resultados da consulta com outra subconsulta. Os resultados da consulta nº 1 precisam ser recuperados onde os resultados da SubQuery correspondem. Tipo de associação .. Por exemplo, selecione a tabela nº 1 dos clientes que também fizeram a tabela nº 2
IN é recuperar se o valor de uma coluna específica estiver em IN
uma lista (1,2,3,4,5). Por exemplo, selecionar clientes que residem nos seguintes códigos postais, ou seja, os valores do código postal estão na lista (....).
Quando usar um sobre o outro ... quando sentir que lê adequadamente (comunica melhor a intenção).
A diferença está aqui:
select *
from abcTable
where exists (select null)
A consulta acima retornará todos os registros, enquanto abaixo um retornaria vazio.
select *
from abcTable
where abcTable_ID in (select null)
Experimente e observe a saída.
Qual deles é mais rápido depende do número de consultas obtidas pela consulta interna:
EXISTENTE avalia em verdadeiro ou falso, mas IN compara múltiplos valores. Quando você não sabe que o registro existe ou não, você deve escolher EXIST
O motivo é que o operador EXISTS trabalha com base no princípio “pelo menos encontrado”. Retorna true e para a verificação da tabela uma vez que pelo menos uma linha correspondente foi encontrada.
Por outro lado, quando o operador IN é combinado com uma subconsulta, o MySQL deve processar a subconsulta primeiro e, em seguida, usa o resultado da subconsulta para processar toda a consulta.
A regra geral é que, se a subconsulta contiver um grande volume de dados, o operador EXISTS fornecerá um melhor desempenho.
No entanto, a consulta que usa o operador IN terá um desempenho mais rápido se o conjunto de resultados retornado da subconsulta for muito pequeno.
Meu entendimento é que ambos devem ser os mesmos desde que não lidemos com valores NULL.
O mesmo motivo pelo qual a consulta não retorna o valor para = NULL vs é NULL. http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/
Quanto ao argumento booleano vs comparador, para gerar um valor booleano, ambos os valores precisam ser comparados e é assim que qualquer condição if funciona. Portanto, não entendo como IN e EXISTS se comportam de maneira diferente.
In certain circumstances, it is better to use IN rather than EXISTS. In general, if the selective predicate is in the subquery, then use IN. If the selective predicate is in the parent query, then use EXISTS.
https://docs.oracle.com/cd/B19306_01/server.102/b14211/sql_1016.htm#i28403
Se uma subconsulta retornar mais de um valor, pode ser necessário executar a consulta externa - se os valores na coluna especificada na condição corresponderem a qualquer valor no conjunto de resultados da subconsulta. Para executar esta tarefa, você precisa usar oin
palavra chave
Você pode usar uma subconsulta para verificar se existe um conjunto de registros. Para isso, você precisa usar a exists
cláusula com uma subconsulta. A exists
palavra-chave sempre retorna valor verdadeiro ou falso.
Acredito que isso tenha uma resposta direta. Por que você não verifica isso das pessoas que desenvolveram essa função em seus sistemas?
Se você é desenvolvedor de MS SQL, aqui está a resposta diretamente da Microsoft.
IN
:
Determina se um valor especificado corresponde a qualquer valor em uma subconsulta ou lista.
Especifica uma subconsulta para testar a existência de linhas.
Descobri que o uso da palavra-chave EXISTS geralmente é muito lento (isso é verdade no Microsoft Access). Em vez disso, eu uso o operador join desta maneira: devo-usar-a-palavra-chave-existe-no-sql
EXISTE É mais rápido em desempenho que em. Se a maioria dos critérios de filtro estiver na subconsulta, é melhor usar IN e Se a maioria dos critérios de filtro estiver na consulta principal, é melhor usar EXISTS.
Se você estiver usando o operador IN, o mecanismo SQL verificará todos os registros buscados na consulta interna. Por outro lado, se estivermos usando EXISTS, o mecanismo SQL interromperá o processo de verificação assim que encontrar uma correspondência.
IN
e EXISTS
podem ser equivalentes e transformados um no outro.
JOIN
um substitutoIN
.