개발자

mysql 실행계획 질문드립니다 (조인과 where문 조건 필터링 순서)

2024년 03월 03일조회 69

쿼리는 아래와 같습니다 EXPLAIN SELECT SUM(t.fee) FROM team t INNER JOIN student s ON s.student_id = t.student_id WHERE s.teacher_id = 3 AND t.team_unit in ('SOCCER', 'COOKING'); teacher 테이블과 student 테이블이 있고, student 테이블이 teacher 테이블의 id를 외래키로 갖고 있습니다 student 테이블과 team 테이블이 있고, team 테이블이 student 테이블의 id를 외래키로 갖고 있습니다 위 쿼리는 student와 team을 조인해서 특정 teacher_id와 team _type을 갖는 로우에 대해 fee 컬럼을 sum하는 쿼리입니다 조인은 nested loop 조인 방식으로 돌아갑니다 (인터넷에서 본 예제를 조금 변행해서 문법이 틀릴 수도 있습니다 양해 부탁드립니다) 사진은 해당 쿼리의 실행계획입니다 실행계획 역시 제가 원래 예제에서 약간 변형한거라 실제와 틀린 부분이 있을 수 있습니다 질문: 아래 두 가지 쿼리 실행 동작 과정 중에 어느 것이 맞는 건가요?? 1번 1. 두 테이블을 nested loop로 조인한 뒤 2. teacher_id가 3이고 team_unit이 SOCCER와 COOKING인 로우를 가져온 뒤에 sum 2번 1. student 테이블에서 teacher_id가 3인 로우 select 2. 1번에서 나온 결과를 바탕으로 team 테이블에서 student_id와 student 테이블의 student_id와 일치하는 로우를 nested loop 방식으로 조인, team_unit이 SOCCER와 COOKING인 로우를 가져온 뒤에 sum Where 조건에 명시된 필터 조건이 조인 전에 발생하는 건지 이후에 발생하는 건지 헷갈려서 질문드립니다

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.
profile picture
익명님의 질문

답변 1

인기 답변

김도열님의 프로필 사진

nested loop join은 말 그대로 중첩 루프 (= 루프 속의 루프)이기 때문에, driving 테이블을 먼저 조회하고, 조회 결과의 수 만큼 driven 테이블을 반복 조회하는 방식으로 JOIN 문을 처리합니다. 물론 실제 처리 과정에서는 NL JOIN의 이런 성능적 문제를 보완하기 위해 BNL과 같은 최적화가 개입하지만, 지금은 논외로 하겠습니다. 본문에 있는 예제와 실행 계획을 보면, student 테이블이 driving이고 team이 driven입니다. 먼저 student 테이블에서 teacher_id = 3 이라는 조건을 만족하는 레코드를 찾고 (ref, const), 각각의 레코드에 대해 team 테이블에서 ON 절에 있는 조건 team.student_id = student.student_id (ref, student.student_id) 을 만족하는 레코드를 찾는데, 여기까지는 스토리지 엔진에서 처리합니다. 위 결과를 MySQL 엔진으로 보내면, MySQL 엔진이 WHERE 절의 team_unit in ('SOCCER', 'COOKING') 조건으로 필터링 (Using Where) 하고, 최종 SUM 집계가 이뤄집니다.

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2024년 03월 03일

MySQL은 다양한 최적화 전략을 사용하기 때문에 항상 똑같은 순서로 처리한다고 단정할 수는 없습니다. 그러나, 일반적으로 MySQL의 쿼리 처리 방식이 질문에서 언급한 2번과 유사하게 동작합니다. WHERE절이 조인된 두 테이블 모두에 걸쳐 있을 때, MySQL은 해당 조건들을 최대한 이용하여 필요한 데이터만을 검색하는 것을 선호합니다. 스텝별로 보면 다음과 같습니다: 1. student 테이블에서 teacher_id가 3인 로우를 선택(select)합니다. 2. 위에서 선택된 결과가 team 테이블과 nested loop join 방식으로 조인됩니다. 3. 조인 과정에서 team 테이블의 student_id가 위에서 선택된 student들의 id와 일치하는 것만 가져오며, team_unit이 SOCCER 혹은 COOKING인 로우만 선택됩니다. 4. 마지막으로, 여기서 SUM(t.fee) 연산이 수행됩니다. 즉, where 절에 명시된 조건들은 가능한 한 조인 이전에 필터링되어(early pruning), 불필요한 row의 join 연산을 최소화하는 데 사용됩니다. 이는 크게 성능 향상에 기여합니다. 다만, 위 설명은 "일반적"인 경우를 가정하였고 실제 동작은 인덱스 유무, 데이터 분포, 테이블 크기 등 여러 요인에 의해 달라질 수 있습니다. 실제 연산 과정을 확인하려면 EXPLAIN 쿼리를 사용하면 됩니다.

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!