복붙노트

[SQL] 하위 쿼리는 IN 대 EXISTS - MySQL의

SQL

하위 쿼리는 IN 대 EXISTS - MySQL의

아래 두 쿼리는 하위 쿼리입니다. 모두 동일하고 모두 나를 위해 잘 작동합니다. 그러나 문제는 방법 1 개 쿼리 방법 2 쿼리가 1 초 정도 소요됩니다 동안 실행하는 데 약 10 초 소요됩니다.

나는 방법 2로 방법 1 개 쿼리를 변환 할 수했지만, 난 쿼리에서 무슨 일이 일어나고 있는지 이해가 안 돼요. 나는 나 자신을 알아 내려고 노력하고있다. 정말 두 개의 질의 아래의 방법과 성능 향상이 일어나지 않는 차이는 무엇을 배울 하시겠습니까? 그 뒤에 논리는 무엇인가?

나는이 사전 기술에 새로운 해요. 나는 누군가가 여기에 나를 도움이되기를 바랍니다. 나는 나에게 단서를 제공하지 않는 문서를 읽어 볼 것을 감안할 때.

방법 1 :

SELECT
   *       
FROM
   tracker       
WHERE
   reservation_id IN (
      SELECT
         reservation_id                                 
      FROM
         tracker                                 
      GROUP  BY
         reservation_id                                 
      HAVING
         (
            method = 1                                          
            AND type = 0                                          
            AND Count(*) > 1 
         )                                         
         OR (
            method = 1                                              
            AND type = 1                                              
            AND Count(*) > 1 
         )                                         
         OR (
            method = 2                                              
            AND type = 2                                              
            AND Count(*) > 0 
         )                                         
         OR (
            method = 3                                              
            AND type = 0                                              
            AND Count(*) > 0 
         )                                         
         OR (
            method = 3                                              
            AND type = 1                                              
            AND Count(*) > 1 
         )                                         
         OR (
            method = 3                                              
            AND type = 3                                              
            AND Count(*) > 0 
         )
   )

방법 2 :

SELECT
   *                                
FROM
   `tracker` t                                
WHERE
   EXISTS (
      SELECT
         reservation_id                                              
      FROM
         `tracker` t3                                              
      WHERE
         t3.reservation_id = t.reservation_id                                              
      GROUP BY
         reservation_id                                              
      HAVING
         (
            METHOD = 1 
            AND TYPE = 0 
            AND COUNT(*) > 1
         ) 
         OR                                                     
         (
            METHOD = 1 
            AND TYPE = 1 
            AND COUNT(*) > 1
         ) 
         OR                                                    
         (
            METHOD = 2 
            AND TYPE = 2 
            AND COUNT(*) > 0
         ) 
         OR                                                     
         (
            METHOD = 3 
            AND TYPE = 0 
            AND COUNT(*) > 0
         ) 
         OR                                                     
         (
            METHOD = 3 
            AND TYPE = 1 
            AND COUNT(*) > 1
         ) 
         OR                                                     
         (
            METHOD = 3 
            AND TYPE = 3 
            AND COUNT(*) > 0
         )                                             
   )

해결법

  1. ==============================

    1.정확히 사용해야가 존재하는 이유 계획을 보여준 것입니다 설명한다. 일반적으로 문제는 백작 (*) 대 존재 온다. 존재는 더 빠르다. 왜?

    정확히 사용해야가 존재하는 이유 계획을 보여준 것입니다 설명한다. 일반적으로 문제는 백작 (*) 대 존재 온다. 존재는 더 빠르다. 왜?

    그러나이 중 하나를 잊지 마세요 :

    자세한 내용 참조 :

  2. ==============================

    2.내가 어떤 결과를로드하지 않는 MySQL의 연산자를 EXISTS 사용하고 있기 때문에 방법 2 빠릅니다. 귀하의 문서에서 언급 한 바와 같이이를 생략합니다 SELECT 절에가 무엇이든,뿐만 아니라 연결합니다. 기준과 일치하는 제 값 대 단 한번 검사가 TRUE 상태 및 추가 처리를 위해 이동 세트 발견.

    내가 어떤 결과를로드하지 않는 MySQL의 연산자를 EXISTS 사용하고 있기 때문에 방법 2 빠릅니다. 귀하의 문서에서 언급 한 바와 같이이를 생략합니다 SELECT 절에가 무엇이든,뿐만 아니라 연결합니다. 기준과 일치하는 제 값 대 단 한번 검사가 TRUE 상태 및 추가 처리를 위해 이동 세트 발견.

    다른 측면에서 방법 (1)는 모든 가능한 값들을로드 연산자 IN 보유하고이를 일치한다. 정확하게 일치하는 시간이 걸리는 과정이다 발견되는 경우에만 조건이 TRUE 설정됩니다.

    따라서 귀하의 방법 2가 빠릅니다.

    희망이 도움이 ...

  3. ==============================

    3.EXISTS 연산자는 부울 연산자가 참 또는 거짓으로 돌아갑니다. is 연산자는 종종 "존재"상태를 테스트하는 서브 쿼리에 사용된다 존재한다.

    EXISTS 연산자는 부울 연산자가 참 또는 거짓으로 돌아갑니다. is 연산자는 종종 "존재"상태를 테스트하는 서브 쿼리에 사용된다 존재한다.

    SELECT 
        select_list
    FROM
        a_table
    WHERE
        [NOT] EXISTS(subquery);
    

    서브 쿼리는 어떤 행을 반환하는 경우, 그렇지 않으면 false를 반환, 운영자 true를 반환 존재한다.

    또한,는 일치하는 행을 찾으면 오퍼레이터는 즉시 처리를 종료한다 더 존재한다. 이러한 특성이 있기 때문에, 당신은 어떤 경우에 쿼리의 성능을 향상시키기 위해 EXISTS 연산자를 사용할 수 있습니다.

    NOT 연산자는 연산자 존재 부정. 서브 쿼리는 어떤 행을 반환하지 않는 경우 즉,하지, 그렇지 않으면 false를 반환 true를 돌려줍니다 존재한다.

    당신은 하위 쿼리에서 SELECT *, SELECT 열, SELECT a_constant, 또는 아무것도 사용할 수 있습니다. MySQL은 SELECT 절에 나타나는 select_list을 무시하기 때문에 결과는 동일합니다.

    그 이유는이 "적어도 발견"원칙에 기반 운영자 작동 존재한다는 것입니다. 그것은 true를 돌려 적어도 하나의 일치하는 행이 발견되면 테이블을 스캔 중지합니다.

    다른 손에서, IN 연산자는 하위 쿼리와 결합 될 때, MySQL은 먼저 하위 쿼리를 처리 한 후 전체 쿼리를 처리하는 하위 쿼리의 결과를 사용해야합니다.

    일반적인 어림짐작가 부질 많은 양의 데이터를 포함하는 경우, 운영자가 더 나은 성능을 제공하고 있는지이다.

    서브 쿼리에서 반환 된 결과 집합이 매우 작은 경우, IN 연산자를 사용하는 쿼리를 빠르게 수행합니다.

    상세 설명과 예제 : MySQL은 EXISTS - mysqltutorial.org

  4. ==============================

    4.당신이 "WHERE t3.reservation_id = t.reservation_id"처럼이있어 때문에 두 번째 방법은 빠릅니다. 첫 번째 경우에는 귀하의 하위 쿼리 정보를 확인하기 위해 테이블에 전체 검사를 수행한다. 그러나 2O 방법에 서브 쿼리는과가 다음을 갖는 상태를 체크 발견되면보고 정확히 알고있다.

    당신이 "WHERE t3.reservation_id = t.reservation_id"처럼이있어 때문에 두 번째 방법은 빠릅니다. 첫 번째 경우에는 귀하의 하위 쿼리 정보를 확인하기 위해 테이블에 전체 검사를 수행한다. 그러나 2O 방법에 서브 쿼리는과가 다음을 갖는 상태를 체크 발견되면보고 정확히 알고있다.

  5. ==============================

    5.그들의 공식 Documentation.SubQuery 최적화로 존재

    그들의 공식 Documentation.SubQuery 최적화로 존재

  6. from https://stackoverflow.com/questions/14190788/subqueries-with-exists-vs-in-mysql by cc-by-sa and MIT license