무조건 잘못되었다 하는 것이 아니라 본인의 경험담을 하나 작성하면
본인은 과도한 서브쿼리 남발로 사수한테 많이 혼났었다.
블로그 글을 보다가 서브쿼리라는 글이 있어서
간만에 서브쿼리가 뭐였더라 하면서
왜 서브쿼리 때문에 혼났었지 하고 곰곰이 되내어 보다가
서브쿼리의 내용을 보고 바로 떠올랐다.
아 이래서 혼났었구나
그렇다면 서브쿼리란 무엇인가?
백문이 불여 일견 예시로 들만한 쿼리문 하나를 짜 보겠다.
-- 블로그에서 좋아요 한 사람들의 사용자 정보를 가져오는 쿼리라고 가정했을 경우
SELECT USERNAME,USERID,AGE,ADRESS
FROM USERPROFILE
WHERE USERID IN (SELECT USERID
FROM LIKEUSER
WHERE LIKETYPE = 'LIKE'
AND POSTID = 1)
결론적으로 이야기 하자면
서브쿼리를 써서 혼난 것이 아니라
서브쿼리를 쓰지 말아야 하는 곳에서
서브쿼리를 사용했기 때문이고
부득이한 상황이 아니라
더 나은 선택지가 있음에도 편리하다는 이유로
서브쿼리를 사용했기 때문에 혼난 것인데
지금 본인은 일을 잘못해서 혼났다를 피력하려는 것이 아니라
서브쿼리를 사용하면 안되는 상황과
안되는 이유를 적고자 하는 취지이다.
서브쿼리는 개발자 입장에서는
결과를 바로 확인하기 편하고
거의 테스트 쿼리에서 꼼수로
땜빵 코딩을 하다가 서브 쿼리를 짜는 경우가 많다.
특정 게시글에서 좋아요한 사람들의 아이디를 먼저 뽑아본 뒤
IN 절 안에 우겨넣게 되면
간단하게 사용자 이름과 아이디, 나이, 주소 등을
뽑아낼 수 있는 상황이 저 예시문이다.
그러나 저 예시 쿼리문은 사용해서 안되는 이유가 있다.
우선 IN 절에서는 DB 인덱스가 타지 않는다.
그 말인 즉 인덱스 스캔을 하지 않고 풀 스캔을 한다는 것인데
이전에 작성한 데이터베이스 관련 글에도 있지만
풀스캔은 테이블 전체를 검색하므로
막대한 부하를 발생시킨다.
두번째로 IN 절 안에 있는 쿼리문도 문제인데
좋아요를 누른 사용자를 찾기 위해 조회한 검색절에
키 컬럼이 들어가 있지 않다.
기본키 나 인덱스나 거의 동일한데
안쪽에서 동작한 쿼리도 인덱스 스캔이 일어나지 않아
테이블 풀 스캔이 일어났다.
결과적으로는 두 테이블 모두 인덱스 스캔을 사용하지 않고
조회를 했으므로
USER 테이블의 행수 컬럼수 LIKEUSER 테이블의 행수 만큼의
테이블 스캔이 발생하였다는 소리이다.
이러한 경우라면 좀 더 나은 선택지가 있기는 하다.
우선 테이블 조회 시 권장 되는 것은
기본적으로 조인은 제일 왼쪽이 기준이므로
기준 테이블의 행 수가 적게 가져가는 것이 효율적이나
조인이나 검색절 사용 시점에 인덱스로 잡아야 할 대상이 많은 경우
인덱스를 가장 많이 가지고 있는 테이블을 기준 테이블로 가져가야 한다.
또한 IN 절에 서브쿼리를 사용하기 보다는 조인을 많이 권장하는데
메인테이블에서 인덱스로 조인을 할 경우에는 풀 스캔이 일어나지 않고
인덱스 스캔이 일어나서 디비 옵티마이저가 동작하게 된다.
인덱스 컬럼이 아닌 검색 조건을 써야 하는 경우도 있을 거긴 한데
테이블 풀 스캔이 가장 덜 일어나는 방식이 데이터베이스 관리에 더 효율적이다.
내부 테스트 상에서는 데이터의 양이 적고
실제 서비스에서 일어나는 만큼의 트랜잭션은 발동하지 않기 때문에
개발 테스트 할 때에는 별로 인지하지 못할 수도 있지만
데이터가 방대해지고 서비스가 추가되다 보면 최적화를 간과해서
엄청난 데이터베이스 과부하가 걸리는 경우를 많이 내봤던 기억이 있다.
프로그램의 알고리즘 최적화도 무엇보다 중요하지만
아직까지는 RDBMS를 완전히 배제할 수 없는 소프트웨어 개발의 특성 상
프로그램만 가지고 대용량의 데이터를 관리하겠다는 것은 분명 무리수이다.
조금 규모 있는 곳이라고 한다면 개발자가 따로 있고 DBA가 따로 있으며
지금 배우고 있는 부트캠프도 프론트엔드와 백엔드가 분리되어 있지만
그 전에는 프로그램 개발자가 DB도 관리해야 하는 방식이어서
데이터 베이스를 대충하고 넘어갈 수 없었고 때문에 정말 많이 애를 먹었다.
무엇보다도 어지간한 큰 규모의 회사가 아니면
아마 DBA는 구경도 못해볼 것이다.
본인도 여지껏 이런 계통 일을 해오면서
DBA 직무 담당자를 한번도 본 적이 없을 정도이니
개발자가 데이터베이스도 관리해야 한다라고 생각하는 것이 더 속 편하다.
서브쿼리라고 하는 것은 데이터베이스 쿼리 작성 기법 중 일부일 뿐이고
데이터베이스 관리 기술은 더 많이 있다.
그러한 부분을 더 공부해야 하는데 일단 벨로그에는 없는 것 같고
다른 기술 블로그 사이트를 뒤저보면서 공부해야 겠다.