서브쿼리는 쿼리 안에 또 다른 쿼리를 하는 문법을 말한다. 기본적으로 서브쿼리를 사용하면 성능이 많이 떨어지는데 같은 서브쿼리를 사용하더라도 어디에 어떤 식으로 사용하느냐에 따라 성능 차이가 날 수 있다.
에시로 최근에 회사에서 쿼리를 사용했는데 스칼라 서브쿼리를 사용했을 때는 2.7-2.8초 정도의 속도가 걸렸는데 이를 인라인 뷰로 변경하고 나서는 0.3초가 걸릴 정도로 성능 차이가 나는 모습을 확인할 수 있었다.
스칼라 서브쿼리(Scalar Subquery)는 SELECT에서 사용한다. 특징으로는 스칼라 서브쿼리의 반환 결과 값은 반드시 하나여야 한다는 점인데 주의해야 할 점으로는 값이 없는 경우엔 NULL로 반환되며 복수인 경우 에러를 발생시킨다.
장점은 단일 값을 반환하기 때문에 메인쿼리와 서브쿼리 간 비교를 수행하기 좋고 필터링 등에도 유리한 점이 있다. 그리고 스칼라 서브쿼리는 입력과 출력에 대해 캐싱하고 있기 때문에 동일한 입,출력을 자주 사용한다면 성능에 이점이 있을 수 있다.
하지만, 반복적으로 실행되는 SELECT 특성상 캐싱된 데이터를 자주 사용하지 않고 입력과 출력이 다른 결과의 쿼리가 반복된다면 매번 쿼리를 실행하고 캐싱하기 때문에 성능이 떨어질 수 있다. 때문에 스칼라 서브쿼리의 단점은 반복이다.
이 외에도 복잡한 연산 등을 인라인 뷰로 전체 적용하여 테이블에 캐싱하는 것 보다 실행되는 로우마다 개별로 실행해 캐싱하는 게 오버헤드가 더 적을 수 있고 스칼라 서브쿼리를 위한 인덱싱이 잘 되어 있다면 성능이 더 좋을 수도 있다.
오라클은 스칼라 서브쿼리의 입력과 출력 값을 내부 캐시(Query Execution Cache)에 저장해 두고 스칼라 서브쿼리가 실행될 때 입력 값을 캐시에서 먼저 찾고 데이터가 있으면 저장되어 있는 출력 값을 리턴해 준다. 캐시에서 입력 값을 찾지 못 한 경우 쿼리를 실행하고 다시 내부 캐시에 저장해 둔다.
인라인 뷰(Inline View)는 FROM에서 사용한다. 간단하게 하나의 캐시 테이블이 생성된다고 보면 되는데 쿼리의 가독성을 향상시키고 쿼리를 쉽게 쓸 수 있고 재사용도 가능하다. 하지만 재사용하기 위해 코드의 중복이 발생할 수있고 서브쿼리의 결과가 큰 경우 성능 문제가 생겨 최적화가 필요할 수도 있다.
서브쿼리는 보통 WHERE에서 사용되지만 다양한 곳에서도 사용이 가능하다. 다양한 형태와 행, 열을 반환할 수 있고 복잡한 연산을 사용할 때 좋다. 하지만 가독성이 떨어지고 연산 비용이 추가되며 유지보수가 어려워지는 문제가 있으며 성능 최적화가 필요한 경우가 있다.