본문 바로가기
프로그래밍/MySQL

📊 [SQL] 제47장 SQL 성능을 생각하는 습관 - 같은 결과라도 더 빠르게 만들 수 있을까요?

by 강릉바다의 블로그 2026. 8. 21.

제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로 무엇을 할 수 있을까요?"

다음 장에서 그 답을 찾아봅시다.