안녕하세요.
SQL 실행 순서 관련해서 고민되는 부분이 있어서 글 올립니다.
개요
우선 실행 순서가 쿼리문에 JOIN이 있는 경우 WHERE 절보다 JOIN, ON 절을 먼저 필터링하고, WHERE 절을 타는 것으로 알고 있습니다.
ex) FROM > ON > JOIN > WHERE > GROUP BY > ..
예시 쿼리
-- WHERE 절에 기준 테이블 조건 검색 (1번째 SQL) SELECT * FROM table1 A LEFT OUTER JOIN table2 B ON A.col1 = B.col1 WHERE A.regDate BETWEEN '2023-12-01' AND '2023-12-31' -- ON 절에 기준 테이블 조건 검색 (2번째 SQL) SELECT * FROM table1 A LEFT OUTER JOIN table2 B ON A.regDate BETWEEN '2023-12-01' AND '2023-12-31' AND A.col1 = B.col1
질문 사항
만약, 위와 같은 쿼리에서 table1에 regDate에 인덱스가 걸려있다고 했을 때
JOIN, ON 조건을 먼저 보는 경우에 2번째 SQL에서 regDate에 인덱스가 타야된다고 생각되는데 오히려 table1에 대해서 ALL 스캔을 하게 되고,
1번째 SQL에서 WHERE 절에 조건을 걸어주어야 table1에 대해서 인덱스를 타게 됩니다.
다른 사이트 글을 보면 전부 FROM > ON > JOIN > WHERE > GROUP BY > .. 순서로 나오는데,
table1과 table2를 먼저 조인 후에 WHERE 절에 regDate 조건을 탄다면 1번째 SQL 또한 인덱스를 안타는게 맞지 않는지..
오히려 WHERE 조건을 타고, JOIN ON을 수행한다고 봐야 하는지 정확한 내용을 찾을 수 없어서 질문드립니다.
물리적인 실행순서라고 보시면 안되고
논리적인 해석순서라고 보셔야 합니다.
FROM > WHERE > SELECT 순서로 해석되는데
JOIN 은 FROM 에 속한다고 보시면 되고
ON 은 WHERE 에 속한다고 보시면 될 것 겉습니다.
컬럼 조인 조건이 아닌 검색조건의 경우
아우터 조인에 있어서
이 조건이 ON 절에 오는 경우와 WHERE 절에 오는 경우에
아예 결과가 달라집니다.
위 두 쿼리는 아예 다른 쿼리입니다.
위 쿼리는 기간에 해당하는 것만 조회하는 쿼리이고
아래 쿼리는 전체 다 조회하면서
기간에 해당하는 것만 B 를 조인하여 보여주는 쿼리입니다.
기간에 해당하지 않는 B 의 정보는 NULL 로 표시됨