240703(+28) | SQL쿼리를 더 잘 작성할 수 있는 방법

청솔·2024년 7월 4일

SQL

목록 보기
11/23
post-thumbnail

알게 된 것

1. 데이터가 말하는 것

leetcode 1581번 문제때문에 캠프 참석 후 처음으로 멘토링을 받아봤다.
질문의 요지는 아래와 같다.

"동일한 Null 값을 가진 컬럼들인데, 컬럼에 따라 조건문 결과값이 다르게 나옴"

멘토링의 결론은 거래한 가격이라는 amount보다는 좀 더 거래 기록에 가까운 transaction_id(visit)id 가 조건문에 적합하다는 것이었다. 테이블에 여러가지 컬럼들이 있을 때 문제를 해결하기 위해선 어떤 컬럼을 사용해야 하는지, 한번 더 생각해 볼 수 있는 계기였다.

2. 중복을 제거하자

생각의 흐름대로 작성하다 보니 서브쿼리를 많이 쓰게 되었는데, 다른 팀원분들의 쿼리를 보니 굳이 서브쿼리를 사용하지 않아도 되는 부분이었다. 문제점이 뭔지 결론을 내리기 전이 었는데, 멘토링을 통해 제일 큰 문제는 중복되는 쿼리를 작성한다는 것을 알게되었다. (서브쿼리에서도 보여 줬던 것을 밖에서도 보여주는 것) 앞으로 쿼리를 작성 할 때 중복되는 부분은 없는지 살펴보는 습관을 가질 것이다.

3. 내가 놓친 CASE()의 특징

[관련포스팅]

 MAX(CASE WHEN activity_type = 'start' THEN timestamp END) AS start_time
 # activity_type = 'start' 조건을 만족하는 행에 대해 timestamp 값을 반환합니다.
 # 조건을 만족하지 않는 경우 NULL을 반환합니다.

leetcode 1661번을 풀이 할때 한 줄이 이해가지 않아서, 조건을 만족시키는 쿼리들을 각각 작성해 그걸 또 JOIN하는 다소 복잡한 과정을 걸쳤다. 왜 MAX()함수를 사용하는지 이해 하지 못했던건, CASE문이 반환하는 값을 알지 못 했기 때문이다.

하나의 machine의 activity_type에는 'start'와 'end'가 있고, 위 case()문에 따르면 start에 해당하는 timestamp 값과 해당하지 않는 end에 대한 null값이 반환되는 것이다.

max(if(acticity_type='start', timestamp, Null))
#max(case())과 동일한 반환값을 낸다.

배형호 튜터님의 정리

서브쿼리 (Subquery)

서브쿼리는 다른 쿼리 안에 포함된 쿼리입니다. 즉, 한 쿼리의 결과를 다른 쿼리에서 사용할 때 사용됩니다.

장점 😊
가독성: 서브쿼리는 보통 직관적이고 읽기 쉽습니다. 특히, 간단한 작업을 수행할 때 유용합니다.

  • 예시: 특정 조건을 만족하는 레코드를 선택한 후, 그 결과를 기반으로 다른 작업을 할 때.
SELECT name FROM employees WHERE id IN 
(SELECT employee_id FROM sales WHERE amount > 1000);

직관적이고 간단합니다.
캡슐화: 서브쿼리는 별도의 쿼리로 작성되어 있어, 복잡한 로직을 분리하고 관리하기 쉽습니다.

단점 😟
성능: 서브쿼리는 때때로 성능이 떨어질 수 있습니다. 특히, 서브쿼리가 큰 테이블에 대해 수행될 때 성능 저하가 발생할 수 있습니다.

  • 예시: 내부 쿼리가 큰 데이터셋을 다루는 경우.
    복잡성: 여러 개의 서브쿼리가 중첩되면 오히려 가독성이 떨어질 수 있습니다.

조인 (Join)

조인은 두 개 이상의 테이블을 결합하여 하나의 결과 집합을 만드는 데 사용됩니다.

장점 😊
성능: 조인은 일반적으로 서브쿼리보다 빠르게 작동합니다. 특히, 인덱스가 잘 설정된 경우 성능이 매우 우수합니다.

  • 예시: 큰 데이터셋을 다룰 때.
SELECT employees.name, sales.amount
FROM employees
JOIN sales ON employees.id = sales.employee_id
WHERE sales.amount > 1000;```

인덱스가 잘 작동하면 빠른 결과를 얻을 수 있습니다.
명확성: 데이터를 결합하는 논리를 명확하게 표현할 수 있습니다.

단점 😟
가독성: 조인은 처음 배우는 사람에게 다소 복잡하고 이해하기 어려울 수 있습니다.
여러 테이블을 결합할 때 복잡도가 증가합니다.

  • 유지보수: 복잡한 조인 쿼리는 나중에 유지보수하기 어려울 수 있습니다. 특히, 여러 테이블을 다룰 때 논리를 이해하기 어려워질 수 있습니다.

인덱스 (Index)

데이터베이스에서 테이블의 데이터를 빠르게 검색하기 위해 사용하는 데이터 구조입니다. 인덱스는 책의 색인과 비슷합니다. 색인을 통해 특정 단어를 찾는 것처럼, 데이터베이스 인덱스를 통해 특정 행을 빠르게 찾을 수 있습니다.

인덱스의 장점

  • 빠른 검색: 인덱스는 특정 데이터를 빠르게 찾을 수 있게 해줍니다.
  • 효율적인 정렬: 인덱스는 데이터를 정렬된 순서로 저장하므로, 정렬된 데이터를 빠르게 접근할 수 있습니다.

인덱스의 단점

  • 저장 공간: 인덱스를 유지하기 위해 추가적인 저장 공간이 필요합니다.
  • 쓰기 성능 저하: 데이터를 삽입하거나 업데이트할 때, 인덱스도 함께 업데이트되어야 하므로 쓰기 작업이 느려질 수 있습니다.

왜 인덱스 덕분에 조인이 빨라지는가?

조인은 두 개 이상의 테이블을 결합하여 하나의 결과 집합을 만드는 작업입니다. 인덱스는 조인 성능을 크게 향상시킬 수 있습니다. 그 이유는 다음과 같습니다.

  • 빠른 행 검색: 인덱스는 특정 조건에 맞는 행을 빠르게 찾을 수 있게 해줍니다. 조인할 때, 인덱스가 있는 열을 사용하면 일치하는 행을 빠르게 찾을 수 있습니다.
  • 효율적인 정렬 및 검색: 인덱스는 데이터를 정렬된 상태로 유지하므로, 조인 시 일치하는 데이터를 찾는 시간이 줄어듭니다.
  • 적은 디스크 I/O: 인덱스는 필요한 데이터만 빠르게 접근할 수 있게 해주므로, 디스크 읽기/쓰기 작업이 줄어듭니다.

요약 📝

서브쿼리

  • 장점: 가독성이 좋고, 간단한 작업에 적합.
  • 단점: 성능이 떨어질 수 있으며, 복잡해질 수 있음.

조인

  • 장점: 성능이 좋고, 명확한 논리 표현 가능.
  • 단점: 처음 배우기 어렵고, 유지보수가 복잡할 수 있음.
    상황에 맞게 서브쿼리와 조인을 선택하면 더 효율적이고 유지보수가 쉬운 SQL 쿼리를 작성할 수 있습니다. 😊
profile
모든 사람이 쉽게 이해할 수 있는 데이터 분석을 지향하는 분석가가 되고 싶습니다. "데이터 분석은 사람을 설득 시킬 수단이다. "

0개의 댓글