2014-09-09 8 views
3

내가 두 테이블 table1table2 그 정의가 있습니다 :보다 효율적인 쿼리

CREATE `table1` (
    'table1_id' int(11) NOT NULL AUTO_INCREMENT, 
    'table1_name' VARCHAR(256), 
    PRIMARY KEY ('table1_id') 
) 

CREATE `table2` (
    'table2_id' int(11) NOT NULL AUTO_INCREMENT, 
    'table1_id' int(11) NOT NULL, 
    'table1_name' VARCHAR(256), 
    PRIMARY KEY ('table2_id'), 
    FOREIGN KEY ('table1_id') REFERENCES 'table1' ('table1_id') 
) 

내가 table2에서 참조되지 table1의 행 수를 알고 싶어, 그 수 다음과 같이 처리하십시오 :

SELECT COUNT(t1.table1_id) FROM table1 t1 
WHERE t1.table1_id NOT IN (SELECT t2.table1_id FROM table2 t2) 

이 쿼리를 수행하는 효율적인 방법이 있습니까? 발견 한 후 실행 계획이기 때문에

답변

2

서브 쿼리와의 세미 조인을 최적화하는 MySQL 5.6으로 업그레이드하십시오.

http://dev.mysql.com/doc/refman/5.6/en/subquery-optimization.html

아니면이 제외를 사용 참조 조인

SELECT COUNT(t1.table1_id) FROM table1 t1 
LEFT OUTER JOIN table2 t2 USING (table1_id) 
WHERE t2.table1_id IS NULL 

또한, table2.table1_id가에 인덱스를 가지고 있는지 확인하십시오.

+0

당신이 제공 한 링크를 통해 읽은 후에, ** 내 IN Ex ** 리조트는 구체화 또는 Exists, 내 경우 Exists .... 그래서 제외 JOIN 또는 NOT EXISTS 전략을 사용해야합니까? –

+1

materialization이 임시 테이블을 만들기 때문에 제외 조인을 계속 사용합니다. EXPLAIN을 사용하여 최적화 계획을 검토하여 두 가지 쿼리 양식을 모두 직접 테스트 할 수 있어야합니다. –

3

사용하려고는하지뿐만 아니라

SELECT COUNT(t1.table1_id) 
FROM table1 t1 
WHERE NOT EXISTS 
( SELECT 1 
    FROM table2 t2 
    WHERE t2.table1_id = t1.table1_id 
) 

이 존재 EXISTS 일반적으로 빠르다과

SELECT COUNT(t1.table1_id) 
FROM table1 t1 
WHERE EXISTS 
( SELECT 1 
    FROM table2 t2 
    WHERE t2.table1_id <=> t1.table1_id 
) 

당신이 그것을 할 수있는 것보다 .. 그 일반적으로 더 효율적인 EXISTS 명중, 조건이 진실하기 때문에 수색을 그만 둘 것이다. IN 문제는 추가 처리 전에 하위 쿼리의 모든 결과를 수집합니다 ... 그리고 그 시간이 더 걸립니다.

@billkarwin이 주석에 언급했듯이 EXISTS는 종속 하위 쿼리를 사용하고 있습니다. 여기에 내 두 가지에 대한 설명이 있습니다. 쿼리 및 OP 쿼리 ... http://sqlfiddle.com/#!2/53199d/5

+2

이 예에서는 외부 쿼리의 고유 한 값마다 실행되는 * 상관 관계가있는 하위 쿼리를 보여줍니다. EXPLAIN으로 시도해보십시오. SUBQUERY DEPENDENT가 표시됩니다. –

+0

@BillKarwin hmm 흥미 롭다. 그래서'EX (INIS)'는'IN()'보다 더 빠릅니까? –

+2

@BillKarwin mysql에서만. SQL의 일반 브랜드는'NOT EXISTS'를 예상대로 처리합니다. – wildplasser

관련 문제