질문 역사:
SQL 쿼리는 처음부터 선언적 방식으로 설계되었으며: "무엇을 얻을 것인가"가 아닌 "어떻게 얻을 것인가"입니다. DBMS의 최적화기는 실행 계획(execution plan)을 생성하여 조인, 필터링, 스캔 및 인덱스 사용의 순서를 정의합니다.
문제:
실행 계획을 이해하지 않으면, 간단해 보이는 쿼리가 왜 너무 느리게 실행되는지, 복잡한 쿼리가 왜 빨리 실행되는지를 설명할 수 없습니다. 잘못된 계획은 불필요한 작업이나 인덱스의 잘못된 사용으로 인해 서버를 몇 시간 동안 차단할 수 있습니다.
해결책:
분석 도구는 EXPLAIN, EXPLAIN ANALYZE (PostgreSQL), SHOW EXPLAIN (MySQL), Management Studio Execution Plan (SQL Server)와 같은 명령어입니다. 이 도구를 사용하면 쿼리가 어떻게 단계별로 실행되었는지, 읽혀진 데이터의 양, 사용된 인덱스, 전체 테이블 스캔(table scan)이 발생한 위치와 지연이 발생한 위치를 볼 수 있습니다.
코드 예제:
EXPLAIN ANALYZE SELECT * FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = 'shipped';
주요 특징:
인덱스를 추가하면 쿼리 속도가 항상 빨라질까요?
아니요! 인덱스는 필드에 대한 필터링이 반환되는 행의 수를 크게 제한할 때만 도움이 됩니다. 대다수의 레코드가 조건에 맞으면 최적화기가 인덱스를 무시할 수 있습니다.
예:
-- 'gender' 필드는 두 개의 값만 가집니다 — 인덱스는 도움이 되지 않습니다. CREATE INDEX idx_gender ON people(gender); SELECT * FROM people WHERE gender = 'M';
JOIN에서 테이블의 순서가 실행 결과에 영향을 미칩니까?
아니요, 최종 데이터는 동일하지만 최적화기는 성능 향상을 위해 조인의 실행 순서를 변경할 수 있습니다. 그러나 특정 JOIN이 작성되거나 "JOIN HINT"와 같은 힌트를 사용하면 순서가 실행의 효율성에 영향을 미칠 수 있습니다.
실행 계획에서 "예상 행수(Estimated rows)"와 "실제 행수(Actual rows)"를 분석하는 이유는 무엇인가요?
두 값의 차이는 테이블의 통계가 오래되었거나 현실과 일치하지 않음을 나타낼 수 있으며, 선택한 계획이 최적이 아니라는 것을 보여줍니다. 통계를 업데이트하거나 쿼리 구조를 재검토해야 합니다.
-- PostgreSQL ANALYZE table_name; -- 통계 업데이트
프로젝트에서 분석가들은 보고서의 "지연"에 대해 오래동안 불만을 표시했습니다. 다섯 개의 JOIN이 포함된 쿼리가 25분 동안 실행되었습니다. 확인결과, 방대한 테이블의 전체 스캔을 선택하는 계획이 발생하여 인덱스 스캔을 사용하지 않았고, 인덱스는 잘못된 필드에 있었으며, 통계는 1년 동안 업데이트되지 않았습니다.
장점:
단점:
실행 계획을 분석하고 실제 필터링 필드에 대한 인덱스를 추가하고 통계를 업데이트했습니다. 쿼리 시간이 20초로 줄어들었습니다. 서버 부하를 대폭 줄였습니다.
장점:
단점: