VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
mysql -u root -p sakila로 클라이언트를 여세요.
상관 서브쿼리의 동작 방식
COLUMN_LIST를 원하는 열로, TABLE_NAME을 테이블로, COLUMN_NAME을 비교되는 열로, AGGREGATE_FUNCTION을 안쪽 쿼리가 실행하는 함수로, OUTER_ALIAS와 INNER_ALIAS를 관련된 테이블의 2개 이름으로 바꾸세요.
이 2개의 별칭이 동작을 가능하게 하는 것입니다: 안쪽 쿼리가 바깥 쿼리를 이름으로 언급하는데, 그것이 상관입니다.
바깥 행마다 한 번씩, 그 행의 값을 채워 넣고 묻는 질문으로 읽으세요.
이것이 답하는 질문
“어떤 영화가 평균보다 긴가”에는 1개의 평균이 필요합니다. “어떤 영화가 자기 등급의 평균보다 긴가”에는 행마다 다른 평균이 필요하고, 상관 서브쿼리가 주는 것이 바로 그것입니다.f2.rating = f.rating이 중요한 줄입니다. 이것이 안쪽 쿼리를 검사 중인 행에 묶어 주므로, G 영화는 G 평균과, R 영화는 R 평균과 비교됩니다.
그 줄을 빼면 서브쿼리는 카탈로그 전체의 평균을 내고, 매번 같은 값이 되며, 쿼리는 다른 질문에 답하게 됩니다.
행마다 한 번씩 실행됩니다
위의 실행 시간을 서브쿼리 레슨의 쿼리들과 비교해 보세요. 그 쿼리들은 측정할 수 없을 만큼 빨리 돌아옵니다. 이 쿼리는 1,000개 행에 10분의 1초가 걸리는데(여러분의 정확한 수치는 다를 것입니다), 서버가 안쪽 쿼리를 한 번이 아니라 바깥 행마다 평가하기 때문입니다. 그것이 트레이드오프의 전부입니다. 상관 서브쿼리는 “각 행을 자기 그룹과 비교하라”를 쓰는 가장 명확한 방법이고, 비용은 테이블과 함께 커집니다. MySQL은 일부 상관 서브쿼리를 스스로 조인으로 다시 쓰고, 같은 질문에 1번의 패스로 답하는 다른 형태도 있습니다. MySQL의 서브쿼리 대 JOIN이 둘 다를 다루고, 어느 쪽을 얻었는지 알려 주는 플랜을 읽는 방법도 다룹니다.요약
- 각 행을 자기 그룹에서 계산한 무언가와 비교하려면 상관 서브쿼리를 사용하세요.
- 안쪽 쿼리가 바깥 쿼리를 이름으로 불러야 하므로, 두 테이블 모두에 별칭을 주세요.
- 바깥 행마다 한 번씩 실행된다고 예상하세요.
- 테이블이 크면 파생 테이블과 조인으로 다시 쓰세요.
함께 보기
- 서브쿼리 — 한 번만 실행되는, 상관되지 않은 종류
- EXISTS — 값이 아니라 검사로 쓰이는 상관 서브쿼리
- 파생 테이블 — 더 저렴한 다시 쓰기
- MySQL의 서브쿼리 대 JOIN — 결정하기 위해 플랜 읽기