SQL을 효율적으로 작성하기 위한 다양한 최적화 팁을 정리해드리겠습니다.
👉 GROUP BY, JOIN, ORDER BY 전에 WHERE로 데이터 양을 줄이는 것이 성능에 유리함
SELECT category, COUNT(*)
FROM products
GROUP BY category
HAVING COUNT(*) > 10; -- HAVING에서 필터링
HAVING은 GROUP BY 이후에 실행되므로 불필요한 연산을 수행할 수 있음SELECT category, COUNT(*)
FROM products
WHERE category IS NOT NULL -- 미리 필터링
GROUP BY category
HAVING COUNT(*) > 10;
👉 필요한 컬럼만 명시적으로 지정하여 불필요한 데이터 조회 방지
SELECT * FROM employees;
SELECT employee_id, name, department FROM employees;
👉 큰 테이블보다 작은 테이블을 먼저 조인하는 것이 성능에 유리함
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)을 먼저 조회하여 성능 최적화👉 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';
👉 서브쿼리 결과가 많은 경우 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');
👉 중복 데이터 제거가 필요 없다면 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 사용하여 성능 개선👉 ORDER BY 대상 컬럼에 인덱스가 있으면 성능이 향상됨
SELECT * FROM employees ORDER BY name;
name 컬럼에 인덱스가 없으면 정렬 비용 증가CREATE INDEX idx_employees_name ON employees(name);
SELECT * FROM employees ORDER BY name;
👉 페이징 처리 시 전체 데이터를 조회하지 않도록 제한
SELECT * FROM employees;
SELECT * FROM employees LIMIT 10; -- MySQL, PostgreSQL
SELECT * FROM (SELECT e.*, ROWNUM rnum FROM employees e) WHERE rnum <= 10; -- Oracle
👉 WHERE 조건을 추가하거나, 불필요한 COUNT 제거
SELECT COUNT(*) FROM orders;
SELECT COUNT(1) FROM orders WHERE status = 'DELIVERED';
👉 자주 조회되는 데이터를 파티셔닝하여 성능 향상
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;
이러한 팁들을 활용하면 SQL 성능을 더욱 최적화할 수 있습니다. 🚀