📊 [SQL] 제47장 SQL 성능을 생각하는 습관 - 같은 결과라도 더 빠르게 만들 수 있을까요?
제47장. SQL 성능을 생각하는 습관
"같은 결과라도 더 빠르게 만들 수 있을까요?"
학습 목표
이번 장을 학습하면 다음 내용을 할 수 있습니다.
- SQL 실행 속도가 중요한 이유를 설명할 수 있다.
- 필요한 데이터만 조회하는 습관을 기를 수 있다.
- SELECT *를 사용할 때의 문제점을 이해할 수 있다.
- WHERE와 JOIN이 성능에 미치는 영향을 이해할 수 있다.
- INDEX가 필요한 상황을 설명할 수 있다.
- 빠르고 효율적인 SQL을 작성하는 습관을 기를 수 있다.
SQL은 항상 빠를까요?
다음 두 SQL을 살펴봅시다.
SELECT *
FROM Products;
그리고
SELECT ProductName, Price
FROM Products;
두 SQL 모두 상품 정보를 조회합니다.
작은 테이블에서는
두 SQL의 속도 차이를 거의 느끼지 못할 수도 있습니다.
하지만 데이터가
10만 건,
100만 건,
1,000만 건으로 늘어난다면 이야기가 달라집니다.
데이터베이스에서는
"얼마나 많은 데이터를 읽어야 하는가?"
가 매우 중요합니다.
실수 ① SELECT *를 습관처럼 사용한다
다음 SQL은 매우 편리합니다.
SELECT *
FROM Customers;
하지만 실제 업무에서는
필요한 열만 선택하는 것이 좋습니다.
예를 들어 고객의 이름과 도시만 필요하다면
SELECT CustomerName, City
FROM Customers;
처럼 작성합니다.
왜 필요한 열만 가져올까요?
테이블에 열이 20개 있다고 생각해 봅시다.
그런데 실제로 필요한 것은
CustomerName
과
City
두 개뿐입니다.
그렇다면
20개의 열을 모두 가져오는 것보다
필요한 2개의 열만 가져오는 것이 효율적입니다.
특히 데이터가 많아질수록
이러한 차이가 커질 수 있습니다.
따라서
필요한 데이터만 가져온다.
라는 습관이 중요합니다.
실수 ② WHERE 없이 많은 데이터를 조회한다
다음 SQL을 실행하면
SELECT *
FROM Orders;
모든 주문을 가져옵니다.
주문 데이터가 100건이라면 문제가 없을 수 있습니다.
하지만 주문 데이터가
1,000만 건이라면 어떨까요?
필요한 주문만 조회하는 것이 좋습니다.
SELECT *
FROM Orders
WHERE CustomerID = 5;
이제 데이터베이스는
CustomerID가 5인 주문을 찾습니다.
필요한 데이터만 찾는 습관
다음 두 SQL을 비교해 봅시다.
SELECT *
FROM Products;
SELECT ProductName, Price
FROM Products
WHERE CategoryID = 1;
두 번째 SQL은
필요한 열과 필요한 행만 조회합니다.
따라서 데이터가 많아질수록
더 효율적인 SQL을 작성하는 데 도움이 됩니다.
실수 ③ JOIN을 아무 생각 없이 사용한다
JOIN은 매우 강력한 기능입니다.
하지만 여러 테이블을 연결하면
처리해야 할 데이터가 많아질 수 있습니다.
예를 들어
SELECT *
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID;
는 고객과 주문을 연결합니다.
필요한 정보가 고객 이름과 주문 번호뿐이라면
다음처럼 작성할 수 있습니다.
SELECT Customers.CustomerName,
Orders.OrderID
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID;
필요한 열만 선택하는 것이 좋습니다.
실수 ④ INDEX를 무조건 많이 만든다
제43장에서 INDEX를 배웠습니다.
INDEX를 사용하면
데이터를 찾는 작업을 빠르게 할 수 있습니다.
그렇다면
"INDEX를 많이 만들면 무조건 좋은 것 아닐까요?"
그렇지 않습니다.
INDEX는 장점만 있는 것이 아닙니다.
INDEX를 많이 만들면
데이터를 INSERT, UPDATE, DELETE할 때
INDEX도 함께 관리해야 합니다.
따라서
필요한 곳에 적절하게 INDEX를 사용한다.
라는 원칙이 중요합니다.
INDEX가 필요한 경우
예를 들어
고객 테이블에서
CustomerID를 이용하여
고객을 자주 찾는다고 생각해 봅시다.
SELECT *
FROM Customers
WHERE CustomerID = 1000;
이러한 검색이 매우 자주 발생한다면
INDEX가 도움이 될 수 있습니다.
예를 들어
CREATE INDEX idx_customer_id
ON Customers(CustomerID);
와 같이 INDEX를 만들 수 있습니다.
그렇다면 모든 열에 INDEX를 만들면 될까요?
아닙니다.
예를 들어 다음처럼
CREATE INDEX idx_name
ON Customers(CustomerName);
CREATE INDEX idx_city
ON Customers(City);
CREATE INDEX idx_country
ON Customers(Country);
모든 열에 INDEX를 만드는 것은 좋은 방법이 아닙니다.
어떤 데이터를
어떤 조건으로
자주 검색하는지를 먼저 생각해야 합니다.
좋은 SQL의 첫 번째 원칙
필요한 데이터만 조회한다.
다음 SQL보다
SELECT *
FROM Products;
필요한 열과 조건을 지정하는 것이 좋습니다.
SELECT ProductName, Price
FROM Products
WHERE CategoryID = 1;
좋은 SQL의 두 번째 원칙
변경하기 전에 확인한다.
UPDATE를 실행할 때는
UPDATE Products
SET Price = Price * 1.1
WHERE CategoryID = 1;
바로 실행하기보다
먼저
SELECT *
FROM Products
WHERE CategoryID = 1;
을 실행합니다.
이것은 성능뿐 아니라
데이터 안전성을 위한 습관이기도 합니다.
좋은 SQL의 세 번째 원칙
필요할 때 INDEX를 사용한다.
INDEX는
데이터를 빠르게 찾기 위한 도구입니다.
하지만 무조건 많이 만드는 것이 아니라
자주 검색하는 조건과 데이터의 양을 고려하여 사용합니다.
좋은 SQL의 네 번째 원칙
JOIN의 조건을 정확하게 작성한다.
다음 SQL을 살펴봅시다.
SELECT *
FROM Customers
JOIN Orders
ON Customers.CustomerID = Orders.CustomerID;
JOIN에서는
어떤 열을 기준으로 연결할 것인지가 매우 중요합니다.
잘못된 조건으로 JOIN하면
원하지 않는 많은 데이터가 만들어질 수 있습니다.
따라서
JOIN은 연결 관계를 먼저 생각하고 작성한다.
라는 습관이 필요합니다.
SQL을 작성하는 개발자의 생각
좋은 개발자는
SQL을 작성할 때
단순히
"문법이 맞는가?"
만 생각하지 않습니다.
다음과 같이 생각합니다.
① 어떤 데이터를 필요한가?
↓
② 얼마나 많은 데이터를 읽는가?
↓
③ 어떤 조건으로 찾는가?
↓
④ 다른 테이블과 연결해야 하는가?
↓
⑤ INDEX가 필요한가?
↓
⑥ 결과가 예상한 것과 같은가?
이러한 사고방식이
바로 SQL 성능을 생각하는 습관입니다.
실제 업무에서는?
학교의 학생 정보 시스템을 생각해 봅시다.
학생이 30명인 학급에서는
데이터를 조회하는 데
큰 문제가 없을 수 있습니다.
하지만
학교 전체 학생이 수천 명이고,
교육청 전체 학생이 수십만 명이라면
데이터베이스의 처리 방법이 중요해집니다.
더 큰 시스템에서는
수백만 건 이상의 데이터가 저장될 수도 있습니다.
따라서
데이터가 많아질수록 SQL을 효율적으로 작성하는 능력이 중요합니다.
많이 하는 실수
실수 ①
무조건 SELECT *를 사용한다.
→ 필요한 열만 선택합니다.
실수 ②
필요하지 않은 데이터까지 모두 조회한다.
→ WHERE로 필요한 데이터만 선택합니다.
실수 ③
모든 열에 INDEX를 만든다.
→ 자주 검색하는 조건을 먼저 생각합니다.
실수 ④
JOIN 조건을 확인하지 않는다.
→ 테이블의 관계와 연결 조건을 먼저 확인합니다.
실수 ⑤
SQL이 실행된다는 이유만으로 좋은 SQL이라고 생각한다.
→ 정확성 + 안전성 + 효율성을 함께 생각합니다.
한눈에 정리
| 습관 | 이유 |
| 필요한 열만 조회 | 불필요한 데이터 처리를 줄인다. |
| WHERE 사용 | 필요한 행만 찾는다. |
| JOIN 조건 확인 | 불필요한 데이터 생성을 예방한다. |
| INDEX 적절히 사용 | 검색 성능을 높일 수 있다. |
| 실행 결과 확인 | 잘못된 SQL을 예방한다. |
이번 장 핵심 정리
✅ SQL은 실행되는 것만으로 충분하지 않다.
✅ 필요한 데이터만 조회하는 습관이 중요하다.
✅ SELECT *는 편리하지만 항상 좋은 방법은 아니다.
✅ WHERE를 이용하여 필요한 데이터만 선택한다.
✅ JOIN을 사용할 때는 테이블의 관계와 조건을 확인한다.
✅ INDEX는 필요한 곳에 적절하게 사용한다.
✅ 좋은 SQL은 정확하고 안전하며 효율적이어야 한다.
연습 문제
기본 문제
① 다음 두 SQL 중 필요한 열만 조회하는 SQL을 고르시오.
① SELECT *
FROM Products;
② SELECT ProductName, Price
FROM Products;
② 다음 SQL에서 데이터를 제한하기 위해 사용하는 절은 무엇인가요?
SELECT *
FROM Products
WHERE CategoryID = 1;
③ INDEX의 주요 목적은 무엇인가요?
응용 문제
다음 SQL을 더 효율적으로 작성해 보세요.
SELECT *
FROM Customers;
조건:
- 고객 이름만 필요합니다.
- 한국 고객만 조회합니다.
도전 문제
다음 SQL의 문제점을 생각해 보세요.
SELECT *
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID;
고객 이름과 주문 번호만 필요하다면
SQL을 수정해 보세요.
정답
기본 문제
① 정답은 ②번입니다.
SELECT ProductName, Price
FROM Products;
필요한 열만 조회하고 있습니다.
② WHERE 절입니다.
WHERE는 원하는 조건에 맞는 행만 선택할 때 사용합니다.
③ INDEX는 데이터 검색을 빠르게 하는 데 도움을 주는 구조입니다.
응용 문제
SELECT CustomerName
FROM Customers
WHERE Country='Korea';
고객 이름만 선택하고
한국 고객이라는 조건도 지정했습니다.
도전 문제
SELECT Customers.CustomerName,
Orders.OrderID
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID;
필요한 열만 선택하여 조회하도록 수정했습니다.
💡 실무 이야기
데이터가 적을 때는
좋지 않은 SQL도
빠르게 실행될 수 있습니다.
그래서 초보 개발자는
"잘 실행되는데요?"
라고 생각하기 쉽습니다.
하지만 데이터가 수십만 건, 수백만 건으로 늘어나면
작은 차이가 큰 차이가 됩니다.
따라서 개발자는 SQL을 작성할 때부터
"지금 데이터가 아니라 데이터가 100배 많아져도 괜찮을까?"
라는 생각을 해야 합니다.
이것이 바로
성능을 생각하는 개발자의 습관입니다.
✨ 다음 장 예고
다음 장에서는 드디어 이 교재에서 배운 SQL을 전체적으로 정리해 보겠습니다.
제1장부터 제47장까지 배운 내용을 돌아보고,
"SQL을 배운 학생이라면 무엇을 할 수 있어야 하는가?"
를 하나씩 확인해 보겠습니다.
또한 실제 업무에서 SQL을 사용할 때 도움이 되는
최종 실무 체크리스트도 만들어 보겠습니다.
마지막으로 여러분이 스스로에게 질문해 봅시다.
"나는 이제 SQL로 무엇을 할 수 있을까요?"
다음 장에서 그 답을 찾아봅시다.