프로젝트에서 쿼리를 튜닝하면서 한가지 궁금증이 생겼다
🎋 쿼리 튜닝을 통한 응답 속도 개선 ( feat. QueryDSL, JPQL )
현재 구현된 서비스의 검색 기능들 중 대부분은 조건이 한 개이다. 물론 다양한 테이블을 join하는 것은 있을수 있지만 검색의 조건이 다양한 것은 조금 다르다고 생각했다기존의 특정 단어로만
latewalk.tistory.com
❓ 궁금증
우리는 서브쿼리를 종종 사용하다보면 그리고 많은 쿼리문을 작성하다보면 언뜻이라도 그런 생각이 든다
어? 이거 조인으로 할 수 있는거 아냐? 혹은 어? 이거 서브쿼리문 작성하면 되겠는데?
그런 쿼리문 중 대부분은 두 개를 같이 써도 같은 결과를 도출해내고는 한다
하지만 튜닝을 좋게 하기 위한 방법으로 서브쿼리는 지양해야 한다고 말한다. 그 이유가 성능 저하라고 하면서 가능하면 Join과 Union등 다양한 방법을 사용해서 같은 결과를 도출하게 하는 것이 좋다고 얘기한다. 왜일까? 그렇다면 서브쿼리는 왜 존재하는 걸까?
물론 두 개 중 하나의 방법만이 정답이 되는 경우도 있겠지만 대부분의 얘기를 하고 싶었다
💦 이유
역시 이유가 바로 나오는 것이 아주 중요하다
서브쿼리를 지양하는 이유 중 가장 큰 이유는 역시 성능 저하이다. 왜 성능이 저하되는 걸까?
이는 데이터가 거대해질수록 그 이유가 명확해진다
서브 쿼리는 SQL 쿼리 내에서 다른 쿼리를 중첩하여 실행하는 방식이다
이게 무슨 말일까?
예를 하나 들어보자
SELECT *
FROM orders
WHERE customer_id = (
SELECT id
FROM customers
WHERE status = 'active'
);
이는 서브쿼리가 단일값을 반환하는 경우 작성되는 Where절에 적용된 서브쿼리이다.
orders의 모든 customer_id 하나하나를 customers의 id와 비교하는 것이다.
orders에 어떤 튜플에 customer_id값을 customers의 모든 id를 비교한다. 그중 status가 active값인 행을 계속해서 비교하는데 서브쿼리는 계속해서 select라는 쿼리를 발생한다는 것이다. 반면에 join은 일일히 select를 실행하지 않기 떄문에 훨씬 더 성능적으로 좋은 결과를 내보낸다.
select 쿼리가 계속해서 발생한다는 것은 만약 orders에 customer_id를 가진 행이 1만개가 있다고 생각해보자 그리고 customers에 존재하는 행도 1만개가 있다면 만약 완전 worst의 경우 모든 행이 1만개의 값을 1만번 비교해야한다.
worst 이중반복문처럼 최악의 경우 1만 * 1만이 되는 것이다. 하지만 Join은 그저 1만번 반복하는 것으로 마치는 성능을 보여줄수 있다는 것이다.
그래서 우리는 서브쿼리를 최소화하고 다른 방법으로 같은 결과를 도출하도록 노력하는 것이 성능에 효과가 있을 것이다.
💢 서운한 성능 결과
만약 위에 말을 듣고 아마 성능 테스트를 진행해본 사람들은 대부분은 실망했을것이다
적어도 저는 실망했습니다...
이유는 결과의 차이가 거의 없었기 때문이다. 왜 별로 차이가 없었던걸까?
- 데이터 양과 인덱스
- 데이터가 5천개뿐이라 크지 않고 id를 기준으로 가져오기 때문에 인덱스가 잘 되어 있다
- 쿼리의 복잡성
- 복잡성이 비슷한 경우 큰 결과의 차이가 없다는 것을 알게되었다
- 데이터베이스의 최적화
- 결국 MySQL로 나의 쿼리가 진행되는데 DB는 가장 효율적인 최적화를 진행한다는 것을 알게되었다. 서브쿼리를 알아서 변환해서 내부적으로 join을 사용해서 가져온다던가 쿼리 최적화가 쿼리를 분석하고 가장 효율적인 실행 계획도 선택한다고 한다.. 와우..
결과적으로 이런 내용을 공부할때마다 드는 생각은 정말 사람들이 똑똑하다는 생각과 정말 발전을 잘했다는 생각이 든다
DB는 스스로 효율적인 방식을 선택하고 우리는 미리 더 효율적인 방식을 선택하기 위해 항상 노력한다
개발자란 무엇인지 더 깊게 생각하게 됐다
💬 참고한 블로그입니다
[MYSQL] 📚 JOIN과 서브쿼리 차이 및 변환 💯 정리
조인(JOIN) vs 서브쿼리(Sub Query) 조인과 서브쿼리는 때로 동일한 결과를 얻을 수 있다. 상황에 따라 조인을 사용하는 것이 훨씬 좋을 때도 있고, 반면에 서브 쿼리를 사용하는 것이 좋을 때도 있다.
inpa.tistory.com
유명한 블로그입니다 여기서 배웠습니다. 또 여기서 서브쿼리를 변경하는 방법과 서브쿼리를 대신 할 수 없는 경우도 말씀해주시더라구요
제가 또 다시 작성하는 것보다 정확한 글로 깔끔하게 설명하신 이곳을 보시는게 더 좋을것 같아 남깁니다.
'CS > 💾 DB' 카테고리의 다른 글
💾 파티셔닝과 샤딩 (0) | 2024.05.31 |
---|---|
💾 JOIN이란?? (0) | 2024.05.31 |
💾 동시성 문제를 해결하는 방법 (0) | 2024.04.27 |
💾 낙관적 락(Optimistic) 과 비관적 락(Pessimisitic) (1) | 2024.04.27 |
💾 MVCC, 트랜잭션 ( 5 ) (feat. MySQL과 PostgreSQL 비교) (1) | 2024.04.27 |
프로젝트에서 쿼리를 튜닝하면서 한가지 궁금증이 생겼다
🎋 쿼리 튜닝을 통한 응답 속도 개선 ( feat. QueryDSL, JPQL )
현재 구현된 서비스의 검색 기능들 중 대부분은 조건이 한 개이다. 물론 다양한 테이블을 join하는 것은 있을수 있지만 검색의 조건이 다양한 것은 조금 다르다고 생각했다기존의 특정 단어로만
latewalk.tistory.com
❓ 궁금증
우리는 서브쿼리를 종종 사용하다보면 그리고 많은 쿼리문을 작성하다보면 언뜻이라도 그런 생각이 든다
어? 이거 조인으로 할 수 있는거 아냐? 혹은 어? 이거 서브쿼리문 작성하면 되겠는데?
그런 쿼리문 중 대부분은 두 개를 같이 써도 같은 결과를 도출해내고는 한다
하지만 튜닝을 좋게 하기 위한 방법으로 서브쿼리는 지양해야 한다고 말한다. 그 이유가 성능 저하라고 하면서 가능하면 Join과 Union등 다양한 방법을 사용해서 같은 결과를 도출하게 하는 것이 좋다고 얘기한다. 왜일까? 그렇다면 서브쿼리는 왜 존재하는 걸까?
물론 두 개 중 하나의 방법만이 정답이 되는 경우도 있겠지만 대부분의 얘기를 하고 싶었다
💦 이유
역시 이유가 바로 나오는 것이 아주 중요하다
서브쿼리를 지양하는 이유 중 가장 큰 이유는 역시 성능 저하이다. 왜 성능이 저하되는 걸까?
이는 데이터가 거대해질수록 그 이유가 명확해진다
서브 쿼리는 SQL 쿼리 내에서 다른 쿼리를 중첩하여 실행하는 방식이다
이게 무슨 말일까?
예를 하나 들어보자
SELECT *
FROM orders
WHERE customer_id = (
SELECT id
FROM customers
WHERE status = 'active'
);
이는 서브쿼리가 단일값을 반환하는 경우 작성되는 Where절에 적용된 서브쿼리이다.
orders의 모든 customer_id 하나하나를 customers의 id와 비교하는 것이다.
orders에 어떤 튜플에 customer_id값을 customers의 모든 id를 비교한다. 그중 status가 active값인 행을 계속해서 비교하는데 서브쿼리는 계속해서 select라는 쿼리를 발생한다는 것이다. 반면에 join은 일일히 select를 실행하지 않기 떄문에 훨씬 더 성능적으로 좋은 결과를 내보낸다.
select 쿼리가 계속해서 발생한다는 것은 만약 orders에 customer_id를 가진 행이 1만개가 있다고 생각해보자 그리고 customers에 존재하는 행도 1만개가 있다면 만약 완전 worst의 경우 모든 행이 1만개의 값을 1만번 비교해야한다.
worst 이중반복문처럼 최악의 경우 1만 * 1만이 되는 것이다. 하지만 Join은 그저 1만번 반복하는 것으로 마치는 성능을 보여줄수 있다는 것이다.
그래서 우리는 서브쿼리를 최소화하고 다른 방법으로 같은 결과를 도출하도록 노력하는 것이 성능에 효과가 있을 것이다.
💢 서운한 성능 결과
만약 위에 말을 듣고 아마 성능 테스트를 진행해본 사람들은 대부분은 실망했을것이다
적어도 저는 실망했습니다...
이유는 결과의 차이가 거의 없었기 때문이다. 왜 별로 차이가 없었던걸까?
- 데이터 양과 인덱스
- 데이터가 5천개뿐이라 크지 않고 id를 기준으로 가져오기 때문에 인덱스가 잘 되어 있다
- 쿼리의 복잡성
- 복잡성이 비슷한 경우 큰 결과의 차이가 없다는 것을 알게되었다
- 데이터베이스의 최적화
- 결국 MySQL로 나의 쿼리가 진행되는데 DB는 가장 효율적인 최적화를 진행한다는 것을 알게되었다. 서브쿼리를 알아서 변환해서 내부적으로 join을 사용해서 가져온다던가 쿼리 최적화가 쿼리를 분석하고 가장 효율적인 실행 계획도 선택한다고 한다.. 와우..
결과적으로 이런 내용을 공부할때마다 드는 생각은 정말 사람들이 똑똑하다는 생각과 정말 발전을 잘했다는 생각이 든다
DB는 스스로 효율적인 방식을 선택하고 우리는 미리 더 효율적인 방식을 선택하기 위해 항상 노력한다
개발자란 무엇인지 더 깊게 생각하게 됐다
💬 참고한 블로그입니다
[MYSQL] 📚 JOIN과 서브쿼리 차이 및 변환 💯 정리
조인(JOIN) vs 서브쿼리(Sub Query) 조인과 서브쿼리는 때로 동일한 결과를 얻을 수 있다. 상황에 따라 조인을 사용하는 것이 훨씬 좋을 때도 있고, 반면에 서브 쿼리를 사용하는 것이 좋을 때도 있다.
inpa.tistory.com
유명한 블로그입니다 여기서 배웠습니다. 또 여기서 서브쿼리를 변경하는 방법과 서브쿼리를 대신 할 수 없는 경우도 말씀해주시더라구요
제가 또 다시 작성하는 것보다 정확한 글로 깔끔하게 설명하신 이곳을 보시는게 더 좋을것 같아 남깁니다.
'CS > 💾 DB' 카테고리의 다른 글
💾 파티셔닝과 샤딩 (0) | 2024.05.31 |
---|---|
💾 JOIN이란?? (0) | 2024.05.31 |
💾 동시성 문제를 해결하는 방법 (0) | 2024.04.27 |
💾 낙관적 락(Optimistic) 과 비관적 락(Pessimisitic) (1) | 2024.04.27 |
💾 MVCC, 트랜잭션 ( 5 ) (feat. MySQL과 PostgreSQL 비교) (1) | 2024.04.27 |