2014-09-02 2 views
0

[요약 질문 : 2 개의 SQL 문은 동일한 결과를 보여 주지만 속도는 다릅니다. 하나의 문은 JOIN을 사용하고 다른 문은 IN을 사용합니다. JOIN 내가 booking_record 이름,이 개 테이블에 SELECT 문의 2 종류의 시도 빠른MySQL (버전 5.5) : 왜`JOIN`이`IN` 절보다 더 빠릅니까?

] IN보다. 테이블 포함 테이블과 many-to-one 관계가 있습니다. 예약 _record.

(표 정의는 간단하게하기 위해 포함되어 있지 않습니다.)

첫 번째 문 : (사용 IN 절)

SELECT 
    id, 
    agent, 
    source 
FROM 
    booking_record 
WHERE 
    id IN 
    (SELECT DISTINCT 
     foreign_key_booking_record 
    FROM 
     inclusions 
    WHERE 
     foreign_key_bill IS NULL 
     AND 
     invoice_closure <> FALSE 
) 

두 번째 문 : 300,000 행 (JOIN 사용)

SELECT 
    id, 
    agent, 
    source 
FROM 
    booking_record 
    JOIN 
    (SELECT DISTINCT 
     foreign_key_booking_record 
    FROM 
     inclusions 
    WHERE 
     foreign_key_bill IS NULL 
     AND 
     invoice_closure <> FALSE 
) inclusions 
    ON 
    id = foreign_key_booking_record 

예약 _record 테이블 가능 및 6,100,000+ 행 포함 내 용 표; 두 번째 성명서는 0.08 초 만에 127 개의 행을 전달했지만 첫 번째 성명서는 동일한 기록으로 거의 21 분이 걸렸습니다.

JOININ 절보다 훨씬 빠릅니까? 내가 가지고있는 경우

+4

나는 당신이 두 문장에'EXPLAIN'를 사용하여 그 결과를 보면이 질문을 탐구하기 시작하는 것이 좋습니다. –

+0

두 번째 필터에는'id = foreign_key_booking_record' 필터가 하나 더 있습니다. –

+0

성능 차이에 대한 가장 일반적인 설명은 생성 된 실행 계획의 차이입니다. 다른 대답이 이미 표시되었으므로,'EXPLAIN'의 결과는 각 쿼리에 대한 실행 계획을 보여줍니다. 'IN (subquery)'에 대한 하나의 큰 성능 문제 : MySQL이 외부 쿼리에 의해 반환 된 모든 행에 대해 해당 하위 쿼리를 실행하고있을 가능성이 있습니다. – spencer7593

답변

2

처럼 만드는 결과를 임시 테이블을 건설 가입

를 입력 here을 볼 수 있습니다.

간단히 말해서 MySQL 버전 5.6.6까지는 MySQL이 이러한 유형의 쿼리를 최적화하지 못했습니다. 그러면 외부 쿼리의 모든 행에 대해 매번 하위 쿼리가 실행됩니다. 오버 헤드가 많고 동일한 쿼리를 반복해서 실행합니다. 좋은 인덱싱을 사용하고 하위 쿼리에서 distinct을 제거하면이 문제를 개선 할 수 있습니다.

성능에 신경 쓰면 exists 대신 in을 선호하는 이유 중 하나입니다.

1

당신에게 내가 IN 버전은 다음 (IN이 일반적으로 매우 비효율적 구조로 간주됩니다 각 항목에 의해 스캔 목록을 구성하는 것으로 의심되는 몇 가지 단서 (Mysql Explain Syntax

을 제공한다 EXPLAIN, 난 단지 그것을 사용 항목의 짧은 목록을 수동으로.이 문제는 잘 문서화입니다.)이 가능성이 더 일반 테이블 사이에 조인.

+0

사진이 나에게 이길 때 : EXPLAIN : P – Giles

1

당신은 Ollie에 의해 말한 것처럼 EXPLAIN을 사용하여 이것을 탐색해야합니다.

그러나 두 번째 명령에는 id = foreign_key_booking_record 필터가 하나 더 있습니다. 이 같은 성능을 가지고있는 경우

확인 :

SELECT 
    id, 
    agent, 
    source 
FROM 
    booking_record 
WHERE 
    id IN 
    (SELECT DISTINCT 
     foreign_key_booking_record 
    FROM 
     inclusions 
    WHERE 
     id = foreign_key_booking_record -- new filter 
     AND 
     foreign_key_bill IS NULL 
     AND 
     invoice_closure <> FALSE 
) 
관련 문제