13.2.10.10 서브 쿼리의 최적화
개발이 진행중이기 때문에 장기간 안정적인 최적화 팁은 없습니다. 다음 목록은 시도해 볼만한 흥미로운 몇 가지 조언을 보여줍니다.
서브 쿼리에서 행의 수와 순서에 영향을 미치는 서브 쿼리 절을 사용합니다. 예 :
SELECT * FROM t1 WHERE t1.column1 IN (SELECT column1 FROM t2 ORDER BY column1); SELECT * FROM t1 WHERE t1.column1 IN (SELECT DISTINCT column1 FROM t2); SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 LIMIT 1);
결합을 서브 쿼리로 바꿉니다. 예를 들어, 다음을 시도하십시오 :
SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN ( SELECT column1 FROM t2);
다음의 대안으로 :
SELECT DISTINCT t1.column1 FROM t1, t2 WHERE t1.column1 = t2.column1;
서브 쿼리를 지원하지 않는 이전 버전의 MySQL과의 호환성을 위해 일부 서브 쿼리를 조인으로 변환 할 수 있습니다. 그러나 경우에 따라서는 서브 쿼리를 조인으로 변환하면 성능을 향상시킬 수 있습니다. 섹션 13.2.10.11 "서브 쿼리의 결합으로 재 작성" 을 참조하십시오.
어구를 서브 쿼리의 외부에서 내부로 이동합니다. 예를 들어, 다음 쿼리를 사용하십시오 :
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);
다음 쿼리의 대안으로 :
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);
다른 예로,이 쿼리를 사용하십시오 :
SELECT (SELECT column1 +5 FROM t1) FROM t2;
다음 쿼리의 대안으로 :
SELECT (SELECT column1 FROM t1) +5 FROM t2;
상관 서브 쿼리 대신 행 서브 쿼리를 사용합니다. 예를 들어, 다음 쿼리를 사용하십시오 :
SELECT * FROM t1 WHERE (column1, column2) IN (SELECT column1, column2 FROM t2);
다음 쿼리의 대안으로 :
SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1 = t1.column1 AND t2.column2 = t1.column2);
a <> ALL (...)
대신NOT (a = ANY (...))
를 사용합니다.x=1 OR x=2
가 아닌x = ANY (
를 사용합니다.table containing (1,2)
)EXISTS
대신= ANY
를 사용합니다.항상 1 개의 행을 반환 비 상관 서브 쿼리의 경우
IN
항상=
보다 느립니다. 예를 들어, 다음 쿼리를 사용하십시오 :SELECT * FROM t1 WHERE t1.
col_name
= (SELECT a FROM t2 WHERE b =some_const
);다음 쿼리의 대안으로 :
SELECT * FROM t1 WHERE t1.
col_name
IN (SELECT a FROM t2 WHERE b =some_const
);
이러한 조언에 따라 프로그램은 빠를도 늦어지는 경우도 있습니다. BENCHMARK()
함수 등의 MySQL 기능을 사용하면 현재의 상황에 어떤 도움이되는지에 대한 아이디어를 얻을 수 있습니다. 섹션 12.14 "정보 함수" 를 참조하십시오.
MySQL 자체가 실시하는 몇개의 최적화를 보여줍니다.
MySQL은 비 상관 서브 쿼리를 한 번만 실행합니다. 특정 서브 쿼리가 실제로 비 상관이되도록하려면
EXPLAIN
을 사용합니다.MySQL은 하위 쿼리 선택 목록 컬럼에 인덱스가 설정 될 가능성을 이용하려고,
IN
,ALL
,ANY
및SOME
서브 쿼리를 다시 작성합니다.MySQL은 다음과 같은 형식의 서브 쿼리를 인덱스 검색 기능을 대체합니다. 이 함수는
EXPLAIN
에 의해 특수한 결합 형 (unique_subquery
또는index_subquery
)로 묘사됩니다.... IN (SELECT
indexed_column
FROMsingle_table
...)MySQL은 다음과 같은 형식의 식을
NULL
값 또는 빈 세트가 포함되어 있지 않은 한,MIN()
또는MAX()
를 포함하는 식으로 확장합니다.value
{ALL | ANY | SOME} {> | <|> = | <=} (uncorrelated subquery
)예를 들어, 다음의
WHERE
절WHERE 5> ALL (SELECT x FROM t)
는 최적화에 의해 다음과 같이 처리 될 수 있습니다.
WHERE 5> (SELECT MAX (x) FROM t)
" MySQL Internals : How MySQL Transforms Subqueries "도 참조하십시오.