programing

SQL에서 EXISTS와 IN의 차이점은 무엇입니까?

powerit 2023. 4. 19. 00:29
반응형

SQL에서 EXISTS와 IN의 차이점은 무엇입니까?

EXISTS ★★★★★★★★★★★★★★★★★」IN"SQL?

요?EXISTS 하면 좋을까요?IN

exists키워드는 이러한 방법으로 사용할 수 있지만 실제로는 카운트를 회피하는 것을 목적으로 하고 있습니다.

--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 ... )

은 '아울러'가 있을 때 입니다.if)existscount.

in있는 경우에 .

 select * from [table]
 where [field] in (1, 2, 3)

in사용하는 것이 더 타당하다join 옵티마이저는 쿼리 옵티마이저는 어느 쪽이든 동일한 계획을 반환해야 합니다. Server 등 오래된 것)에서는 (Microsoft SQL Server 2000 등)이 되고 있습니다.in쿼리는 항상 중첩된 결합 계획을 가져옵니다.join쿼리는 필요에 따라 중첩, 병합 또는 해시를 사용합니다.보다 최신의 실장에서는, 보다 스마트하고, 계획도 조정할 수 있습니다.in용됩니니다다

EXISTS쿼리가 결과를 반환했는지 여부를 알려줍니다. §:

SELECT * 
FROM Orders o 
WHERE EXISTS (
    SELECT * 
    FROM Products p 
    WHERE p.ProductNumber = o.ProductNumber)

IN을 여러할 수 있습니다.

SELECT * 
FROM Orders 
WHERE ProductNumber IN (1, 10, 100)

는 " " " 와 할 수도 있습니다.IN을 사용하다

SELECT * 
FROM Orders 
WHERE ProductNumber IN (
    SELECT ProductNumber 
    FROM Products 
    WHERE ProductInventoryQuantity > 0)

규칙 옵티마이저를 기반으로 합니다.

  • EXISTS가 훨씬 빠르다IN★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
  • INEXISTS★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

비용 최적화 도구에 기반:

  • 차이가 없다.

사용법이 다르기 때문에 그 기능을 알고 있을 것으로 생각되므로, 다음과 같이 질문해 주십시오.SQL을 기존 SQL 대신 IN을 사용하도록 다시 작성하는 것이 좋거나 그 반대일 수 있습니다.

그게 공정한 추정인가요?


편집: 대부분의 경우 IN 기반 SQL을 다시 작성하여 EXISTES를 사용할 수 있으며, 그 반대도 가능합니다. 일부 데이터베이스 엔진에서는 쿼리 최적화 프로그램이 이 두 가지를 다르게 취급합니다.

예:

SELECT *
FROM Customers
WHERE EXISTS (
    SELECT *
    FROM Orders
    WHERE Orders.CustomerID = Customers.ID
)

다음 이름으로 다시 쓸 수 있습니다.

SELECT *
FROM Customers
WHERE ID IN (
    SELECT CustomerID
    FROM Orders
)

또는 조인 포함:

SELECT Customers.*
FROM Customers
    INNER JOIN Orders ON Customers.ID = Orders.CustomerID

원래의 포스터가 IN과 EXIST의 기능에 대해 궁금해하고 있기 때문에 어떻게 사용하는지, 아니면 EXIST를 사용하기 위해 IN을 사용하여 SQL을 다시 쓰는 것이 좋을지, 아니면 그 반대로 하면 좋을지 의문이 남습니다.

  1. EXISTS가 훨씬 빠르다IN★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    INEXISTS서브쿼리 결과가 매우 작을 때 사용합니다.

    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'
    
  2. 쿼리 1

    SELECT
    FROM    t1 
    WHERE   not  EXISTS (SELECT * FROM t2 WHERE t1.id = t2.t1id)
    

    쿼리 2

    SELECT t1.* 
    FROM   t1 
    WHERE  t1.id not in (SELECT  t2.t1id FROM t2 )
    

    있는 t1null Query 는 null.id null을 수 .Query 1은 null을 찾을 수 없습니다.Query 2는 null을 찾을 수 없습니다.

    말은 ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ.IN수 null의 은 null입니다.EXISTS무효로 하다

「 」를하고 있는 는,IN오퍼레이터, SQL 엔진은 내부 쿼리에서 가져온 모든 레코드를 검색합니다.한편, 만약 우리가 그것을 사용하고 있다면EXISTSSQL 엔진은 일치하는 항목을 발견하는 즉시 스캔 프로세스를 중지합니다.

IN은 평등 관계(또는 NOT 에 부등식)만 지원합니다.
=any / =some과 동의어입니다.

select    * 
from      t1 
where     x in (select x from t2)
;

EXISTES는 IN을 사용하여 표현할 수 없는 다양한 유형의 관계를 지원합니다.예를 들어 다음과 같습니다.

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 || '℅'
                  )
;

그리고 다른 관점에서 보면-

EXISTSIN의 성능 및 기술적 차이는 특정 벤더의 구현/제한/버그에서 기인할 수 있지만 대부분의 경우 데이터베이스 내부 이해 부족으로 인해 만들어진 속설일 뿐입니다.

테이블의 정의, 통계의 정확도, 데이터베이스 구성 및 옵티마이저의 버전은 모두 실행 계획 및 성능 메트릭에 영향을 미칩니다.

Existsfalse를 하지만 "true"는 "false"는 "false"입니다.IN키워드는 대응하는 서브쿼리 컬럼의 모든 값을 비교합니다. 하나Select 1 함께 할 수 .Exists명령어를 입력합니다.§:

SELECT * FROM Temp1 where exists(select 1 from Temp2 where conditions...)

★★★★★★★★★★★★★★★★★.IN이 낮기 때문에 '비활성화'를 할 수 있습니다.Exists★★★★★★ 。

생각합니다,

  • EXISTS쿼리 결과를 다른 서브쿼리와 일치시켜야 하는 경우입니다.SubQuery 쿼리 1번 쿼리★★★★★★★★★★★★★★★★。 주문 table.#1은 #2입니다.

  • 이 IN일 .IN(1, 2, 3, 4, 5 ) 。지퍼코드하다

하나를 다른 하나보다 사용할 때...(의도를 더 잘 전달할 수 있습니다)

가 바로는 될 때NULL가 '어느 정도'가 됩니다.NULLEXITS키워드를 지정합니다.하려면 " "를 합니다.IN키워드를 지정합니다.

어느 쪽이 빠른지는 내부 쿼리에서 가져온 쿼리 수에 따라 달라집니다.

  • 내부 쿼리가 수천 개의 행을 가져오는 경우 EXIST를 선택하는 것이 좋습니다.
  • 내부 쿼리가 몇 개의 행을 가져오면 IN이 더 빠릅니다.

EXIST는 참 또는 거짓을 평가하지만 IN에서는 여러 값을 비교합니다.레코드의 존재 여부를 모를 때는 EXIST를 선택해야 합니다.

차이점은 다음과 같습니다.

select * 
from abcTable
where exists (select null)

위 쿼리에서는 모든 레코드가 반환되지만 아래 쿼리에서는 빈 레코드가 반환됩니다.

select *
from abcTable
where abcTable_ID in (select null)

한 번 시험해 보고 출력을 관찰해 보십시오.

그 이유는 EXISTES 연산자가 "최소한 발견된" 원칙에 따라 작동하기 때문입니다.true를 반환하고 일치하는 행이 하나 이상 발견되면 테이블 검색을 중지합니다.

한편 IN 연산자가 하위 쿼리와 결합되면 MySQL은 먼저 하위 쿼리를 처리한 다음 하위 쿼리의 결과를 사용하여 전체 쿼리를 처리해야 합니다.

일반적으로 서브쿼리에 대량의 데이터가 포함되어 있는 경우 EXISTS 연산자가 더 나은 성능을 제공합니다.

그러나 하위 쿼리에서 반환된 결과 세트가 매우 작을 경우 IN 연산자를 사용하는 쿼리는 더 빨리 수행됩니다.

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

제가 알기로는 NULL 값을 취급하지 않는 한 양쪽 모두 같아야 합니다.

쿼리가 = NULL vs. NULL에 대한 값을 반환하지 않는 것과 동일한 이유는 NULL입니다. http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/

boolean vs comparator 인수에 대해서는 boolean을 생성하기 위해서는 양쪽 값을 비교해야 하며, 이것이 if 조건의 동작 방식입니다.그래서 나는 IN과 EXIST가 어떻게 다르게 행동하는지 이해하지 못한다.

서브쿼리가 둘 이상의 값을 반환하는 경우 조건에 지정된 컬럼 내의 값이 서브쿼리의 결과 세트 내의 값과 일치하는 경우 외부 쿼리를 실행해야 할 수 있습니다.하려면 , 「」를 할 필요가 있습니다.in키워드를 지정합니다.

하위 쿼리를 사용하여 레코드 세트가 있는지 확인할 수 있습니다.위해서는 '우리'를 .exists그쿼리그그그exists거짓

나는 이것이 간단한 해답을 가지고 있다고 믿는다.시스템 내에서 그 기능을 개발한 사람에게 확인해 보는 것은 어떨까요?

MS SQL 개발자인 경우 Microsoft에서 직접 답변을 드리겠습니다.

다음과 같습니다IN.

지정된 값이 하위 쿼리 또는 목록의 값과 일치하는지 여부를 결정합니다.

다음과 같습니다EXISTS.

행의 존재 여부를 테스트할 하위 쿼리를 지정합니다.

EXISTS 키워드를 사용하는 것은 매우 느리다는 것을 알게 되었습니다(Microsoft Access에서는 매우 그렇습니다).대신 should-i-use-the-keyword-exists-in-sql과 같은 방법으로 join 연산자를 사용합니다.

where inwhere exists , , , 「 」where in★★★★★★★★★★★★★★★★★★★★★★★★★★

「」를 사용합니다.where in ★★★★★★★★★★★★★★★★★」where exists부모 결과의 모든 결과가 표시됩니다.여기서의 차이점은,where exists이치노방지할 수 , " " " " 입니다.where in더 나은 선택이 될 거야

10,000개의 회사가 있고 각각 10명의 사용자가 있다고 가정합니다(따라서 사용자 테이블에는 100,000개의 엔트리가 있습니다.이제 사용자 이름 또는 회사 이름으로 사용자를 찾고 싶다고 가정합니다.

음 using 를 사용한 다음 쿼리:were exists은 141ms입니다

select * from `users` 
where `first_name` ='gates' 
or exists 
(
  select * from `companies` 
  where `users`.`company_id` = `companies`.`id`
  and `name` = 'gates'
)

이는 각 사용자에 대해 종속 하위 쿼리가 실행되기 때문에 발생합니다.

단, 기존 쿼리를 회피하고 다음을 사용하여 작성하는 경우:

select * from `users` 
where `first_name` ='gates' 
or users.company_id in  
(
    select id from `companies` 
    where  `name` = 'gates'
)

그러면 종속 하위 쿼리는 회피되고 쿼리는 0.012밀리초 후에 실행됩니다.

여기에 이미지 설명 입력

저는 최근에 사용하고 있는 질문에 대해 약간의 연습을 했습니다.원래는 INSER JOINS와 함께 만들었는데, EXISTS와 어떻게 연동되는지 보고 싶었어요.변환했어요.비교하기 위해 두 버전을 여기에 포함하겠습니다.

SELECT DISTINCT Category, Name, Description 
FROM [CodeSets] 
WHERE Category NOT IN (
    SELECT def.Category
      FROM [Fields] f
      INNER JOIN [DataEntryFields] def ON f.DataEntryFieldId = def.Id
      INNER JOIN Section s ON f.SectionId = s.Id
      INNER JOIN Template t ON s.Template_Id = t.Id
    WHERE t.AgencyId = (SELECT Id FROM Agencies WHERE Name = 'Some Agency')
        AND def.Category NOT IN ('OFFLIST', 'AGENCYLIST', 'RELTO_UNIT', 'HOSPITALS', 'EMS', 'TOWCOMPANY', 'UIC', 'RPTAGENCY', 'REP')
        AND (t.Name like '% OH %') 
        AND (def.Category IS NOT NULL AND def.Category <> '')
)
ORDER BY 1

통계는 다음과 같습니다.

변환된 버전은 다음과 같습니다.

SELECT DISTINCT cs.Category, Name, Description 
FROM [CodeSets] cs
WHERE NOT Exists (
    SELECT * FROM [Fields] f
      WHERE EXISTS (SELECT * FROM [DataEntryFields] def 
                       WHERE def.Id  = f.DataEntryFieldId
                           AND def.Category NOT IN ('OFFLIST', 'AGENCYLIST', 'RELTO_UNIT', 'HOSPITALS', 'EMS', 'TOWCOMPANY', 'UIC', 'RPTAGENCY', 'REP')
                           AND (def.Category IS NOT NULL AND def.Category <> '')
                           AND def.Category = cs.Category
                           AND EXISTS (SELECT * FROM Section s 
                                          WHERE f.SectionId = s.Id
                                          AND EXISTS (SELECT * FROM Template t 
                                                        WHERE s.Template_Id = t.Id
                                                           AND EXISTS (SELECT * FROM Agencies 
                                                                          WHERE Name = 'Some Agency' and t.AgencyId = Id)
                                                                             AND (t.Name like '% OH %')
                                                    )
                                        )
                    )
)
ORDER BY 1

그 결과는, 적어도 나에게는 인상적이지 않았다.여기에 이미지 설명 입력

SQL의 구조에 대해 기술적으로 더 잘 알고 있다면 답변을 드릴 수 있지만, 이 예를 참고하여 직접 결론을 내리십시오.

그러나 INSER JOIN 및 IN()은 읽기 더 쉽습니다.

EXIST는 IN보다 퍼포먼스가 빠릅니다.대부분의 필터 기준이 하위 쿼리에 있는 경우 IN을 사용하는 것이 좋고 대부분의 필터 기준이 기본 쿼리에 있는 경우 EXISTS를 사용하는 것이 좋습니다.

IN 연산자를 사용하는 경우 SQL 엔진은 내부 쿼리에서 가져온 모든 레코드를 검색합니다.한편, EXISTES를 사용하고 있는 경우 SQL 엔진은 일치하는 항목을 발견하는 즉시 스캔 프로세스를 중지합니다.

언급URL : https://stackoverflow.com/questions/24929/difference-between-exists-and-in-in-sql

반응형