효율적인 SQL 팁 정리

SQL 공부

목록 보기
1/11

SQL을 효율적으로 작성하기 위한 다양한 최적화 팁을 정리해드리겠습니다.


1. WHERE 절에서 최대한 필터링을 수행

👉 GROUP BY, JOIN, ORDER BY 전에 WHERE로 데이터 양을 줄이는 것이 성능에 유리함

🚫 비효율적인 방법

SELECT category, COUNT(*)
FROM products
GROUP BY category
HAVING COUNT(*) > 10;  -- HAVING에서 필터링
  • HAVINGGROUP BY 이후에 실행되므로 불필요한 연산을 수행할 수 있음

✅ 효율적인 방법

SELECT category, COUNT(*)
FROM products
WHERE category IS NOT NULL  -- 미리 필터링
GROUP BY category
HAVING COUNT(*) > 10;
  • WHERE에서 먼저 필터링하여 연산량을 줄임

2. SELECT * 지양하기

👉 필요한 컬럼만 명시적으로 지정하여 불필요한 데이터 조회 방지

🚫 비효율적인 방법

SELECT * FROM employees;
  • 모든 컬럼을 가져오기 때문에 네트워크 트래픽 증가, 인덱스 최적화 어려움

✅ 효율적인 방법

SELECT employee_id, name, department FROM employees;
  • 사용할 컬럼만 선택하여 조회 성능 향상

3. JOIN 시 작은 테이블을 먼저 활용하기

👉 큰 테이블보다 작은 테이블을 먼저 조인하는 것이 성능에 유리함

🚫 비효율적인 방법 (큰 테이블 먼저)

SELECT e.name, d.department_name
FROM employees e
JOIN departments d ON e.department_id = d.department_id;
  • 큰 테이블(employees)이 먼저 조회되면 불필요한 연산이 많아짐

✅ 효율적인 방법 (작은 테이블 먼저)

SELECT e.name, d.department_name
FROM departments d
JOIN employees e ON e.department_id = d.department_id;
  • 작은 테이블(departments)을 먼저 조회하여 성능 최적화

4. INDEX 활용하기

👉 WHERE, JOIN, ORDER BY, GROUP BY에 사용되는 컬럼에 적절한 인덱스를 추가

🚫 비효율적인 방법 (인덱스 없음)

SELECT * FROM employees WHERE name = 'John';
  • name 컬럼에 인덱스가 없으면 풀 테이블 스캔 발생

✅ 효율적인 방법 (인덱스 추가)

CREATE INDEX idx_employees_name ON employees(name);
SELECT * FROM employees WHERE name = 'John';
  • 인덱스가 적용되어 조회 성능 향상

5. EXISTS vs IN 사용

👉 서브쿼리 결과가 많은 경우 EXISTS가, 작은 경우 IN이 더 효율적임

🚫 비효율적인 방법 (IN 사용, 서브쿼리 결과가 많을 때)

SELECT * FROM employees
WHERE department_id IN (SELECT department_id FROM departments WHERE location = 'NY');
  • 서브쿼리 결과가 많으면 성능 저하

✅ 효율적인 방법 (EXISTS 사용)

SELECT * FROM employees e
WHERE EXISTS (SELECT 1 FROM departments d WHERE d.department_id = e.department_id AND d.location = 'NY');
  • EXISTS는 서브쿼리에서 조건을 만족하는 첫 번째 행을 찾으면 즉시 종료 → 성능 향상

6. UNION vs UNION ALL

👉 중복 데이터 제거가 필요 없다면 UNION 대신 UNION ALL을 사용하여 성능 개선

🚫 비효율적인 방법 (UNION 사용)

SELECT name FROM customers
UNION
SELECT name FROM suppliers;
  • UNION은 중복 제거를 위해 정렬(SORT) 작업을 수행 → 성능 저하

✅ 효율적인 방법 (UNION ALL 사용)

SELECT name FROM customers
UNION ALL
SELECT name FROM suppliers;
  • 중복 제거가 필요 없으면 UNION ALL 사용하여 성능 개선

7. ORDER BY 시 인덱스 활용

👉 ORDER BY 대상 컬럼에 인덱스가 있으면 성능이 향상됨

🚫 비효율적인 방법 (인덱스 없이 정렬)

SELECT * FROM employees ORDER BY name;
  • name 컬럼에 인덱스가 없으면 정렬 비용 증가

✅ 효율적인 방법 (인덱스 추가 후 정렬)

CREATE INDEX idx_employees_name ON employees(name);
SELECT * FROM employees ORDER BY name;
  • 인덱스를 활용하여 정렬 성능 향상

8. LIMIT / ROWNUM 사용하여 불필요한 데이터 조회 방지

👉 페이징 처리 시 전체 데이터를 조회하지 않도록 제한

🚫 비효율적인 방법 (전체 조회 후 일부만 사용)

SELECT * FROM employees;
  • 불필요한 데이터까지 조회하여 성능 저하

✅ 효율적인 방법 (LIMIT 사용)

SELECT * FROM employees LIMIT 10;  -- MySQL, PostgreSQL
SELECT * FROM (SELECT e.*, ROWNUM rnum FROM employees e) WHERE rnum <= 10;  -- Oracle
  • 필요한 데이터만 조회하여 성능 개선

9. COUNT(*) 최적화

👉 WHERE 조건을 추가하거나, 불필요한 COUNT 제거

🚫 비효율적인 방법 (전체 COUNT)

SELECT COUNT(*) FROM orders;
  • 불필요한 데이터까지 계산하여 성능 저하

✅ 효율적인 방법 (특정 조건 COUNT)

SELECT COUNT(1) FROM orders WHERE status = 'DELIVERED';
  • 필요한 데이터만 COUNT하여 성능 최적화

10. PARTITION 활용하여 대량 데이터 처리 최적화

👉 자주 조회되는 데이터를 파티셔닝하여 성능 향상

🚫 비효율적인 방법 (단일 테이블)

SELECT * FROM orders WHERE order_date >= '2024-01-01';
  • 모든 데이터를 스캔해야 하므로 성능 저하

✅ 효율적인 방법 (파티션 사용)

CREATE TABLE orders_partitioned (
    order_id NUMBER,
    order_date DATE,
    customer_id NUMBER
)
PARTITION BY RANGE (order_date) (
    PARTITION p2023 VALUES LESS THAN (TO_DATE('2024-01-01', 'YYYY-MM-DD')),
    PARTITION p2024 VALUES LESS THAN (TO_DATE('2025-01-01', 'YYYY-MM-DD'))
);
SELECT * FROM orders_partitioned PARTITION (p2024) WHERE customer_id = 100;
  • 필요한 데이터만 조회하여 성능 최적화

📌 마무리

  1. WHERE로 최대한 미리 필터링
  2. SELECT * 대신 필요한 컬럼만 선택
  3. 작은 테이블을 먼저 JOIN
  4. INDEX를 활용하여 조회 성능 개선
  5. EXISTS vs IN 적절히 사용
  6. UNION 대신 UNION ALL 사용하여 중복 제거 비용 절감
  7. ORDER BY 시 인덱스 활용
  8. LIMIT / ROWNUM으로 불필요한 데이터 조회 방지
  9. COUNT(*) 최적화
  10. PARTITION으로 대량 데이터 최적화

이러한 팁들을 활용하면 SQL 성능을 더욱 최적화할 수 있습니다. 🚀

profile
AI 답변 글을 주로 올립니다.

0개의 댓글