MySQL / ORACLE 의 GROUP BY 동작 차이
원래 MySQL만 사용했는데 취업을 해보니 많은 회사들이 ORACLE을 사용하고 있다는 것을 알게되었다. 그리고 개발자는 프로그래밍보다 중요한 것이 SQL 작성 능력임도 알게되었다.
그래서 요즘 SQL 문제를 열심히 풀고 있는데 그룹화 문제에서 다음과 같은 에러를 만났다.
GROUP BY 절 이후 컬럼
https://school.programmers.co.kr/learn/courses/30/lessons/144856
이 문제의 정답 쿼리로 예를 들겠다.
SELECT
a.author_id,
a.AUTHOR_NAME,
b.CATEGORY,
sum(price * SALES) as TOTAL_SALES
FROM BOOK b, AUTHOR a, BOOK_SALES bs
WHERE
b.AUTHOR_ID = a.AUTHOR_ID
AND bs.BOOK_ID = b.BOOK_ID
AND TO_CHAR(bs.SALES_DATE, 'MM') = '01'
GROUP BY a.author_id
ORDER BY a.author_id, b.category DESC;
이 쿼리를 오라클로 돌리면 위와 같은 에러가 발생한다. 하지만 MySQL로 돌리면 에러가 발생하지 않는다.
결론부터 말하면 MySQL은 GROUP BY 절 뒤에 PK가 들어간다면 모두가 유일한 행이라고 가정한다. 그러나 오라클은 PK가 들어간다고 해서 모두가 유일한 행이라고 가정하지 않는다.
조인을 하면 PK가 PK 성질을 잃어버리는 일이 허다하기 때문에 오라클은 PK가 들어간다고 해서 그것을 유일하다고 보지 않는 것이다. MySQL도 옵션을 켜면 오라클처럼 SELECT 할 모든 컬럼을 GROUP BY 에 넣어줘야한다.
위 코드도 MySQL에서실행하면 에러는 발생하지 않아도 정답으로 처리되지 않는다. 그룹화할 요소가 더 많은데 개발자의 휴먼에러가 개입할 여지를 남겼기 때문이다.
실행방식 차이
MySQL은 기본적으로 정렬, 임시 테이블 기반으로 그룹화를 진행한다.
그룹화한 대상을 기준으로 정렬하면서 그룹화를 진행하기 때문에 데이터셋이 크면 효율이 좋지 않으며 인덱스를 사용하면 더 효율을 높힐 수 있다.
반면 오라클은 Hash Group By 방식으로 해시 테이블을 생성하고 데이터를 해싱하여 그룹화한다. 이 방식은 정렬 없이도 빠르게 그룹화 가능하며 특히 대용량 데이터에서 유리하다. 그러나 메모리를 많이 사용한다.