SQL Plan Studio의 AI 조언 기능이 항상 효과적인 것은 아닙니다. 같은 문제에 대해 실행할 때마다 다른 답변을 제시하거나, 효과 없는 해결책을 제안하기도 합니다.
•
SQL Plan Studio는 PostgreSQL과 MySQL의 복잡한 실행계획을 보기 쉽게 정리해주어 쿼리 성능 분석과 튜닝에 도움을 주는 무료 도구입니다.
테스트 대상 SQL
아직 출간 전인『SQL TUNER for PostgreSQL』 책의 '8-4-4. 조인 횟수를 줄이자' 예제를 사용했습니다.
원본 SQL 및 성능
•
실행시간: 5.5초
•
주요 병목: 약 184만 건의 대량 데이터 조인
SELECT t1.shop_id ,TO_CHAR(t2.ord_dtm,'YYYYMM') ord_ym
,MAX(t1.shop_nm) shop_nm ,SUM(t2.ord_amt) ord_amt_sum
FROM startdbpg.ms_shop_big t1
INNER JOIN startdbpg.tr_ord_big t2
ON (t1.shop_id = t2.shop_id)
WHERE t2.ord_dtm >= '2024-01-01'::date
AND t2.ord_dtm < '2024-04-01'::date
GROUP BY t1.shop_id ,TO_CHAR(t2.ord_dtm,'YYYYMM')
ORDER BY t1.shop_id ,TO_CHAR(t2.ord_dtm,'YYYYMM');
GroupAggregate (actual time=4292.063..5125.705 rows=867 loops=1)
Group Key: t1.shop_id, (to_char(t2.ord_dtm, 'YYYYMM'::text))
Buffers: shared hit=10 read=26860, temp read=18726 written=18763
-> Sort (actual time=4289.157..4674.781 rows=1848528 loops=1)
Sort Key: t1.shop_id, (to_char(t2.ord_dtm, 'YYYYMM'::text))
Sort Method: external merge Disk: 74928kB
Buffers: shared hit=10 read=26860, temp read=18726 written=18763
-> Hash Join (actual time=71.046..3180.073 rows=1848528 loops=1)
Hash Cond: ((t2.shop_id)::text = (t1.shop_id)::text)
Buffers: shared hit=7 read=26860
-> Index Scan using tr_ord_big_x23 on tr_ord_big t2 (actual time=0.102..2057.898 rows=1848528 loops=1)
Index Cond: ((ord_dtm >= '2024-01-01'::date) AND (ord_dtm < '2024-04-01'::date))
Buffers: shared hit=3 read=26860
-> Hash (actual time=60.800..60.803 rows=300 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 24kB
Buffers: shared hit=4
-> Seq Scan on ms_shop_big t1 (actual time=60.308..60.706 rows=300 loops=1)
Buffers: shared hit=4
Planning:
Buffers: shared hit=145 read=1
Planning Time: 15.266 ms
Execution Time: 5554.166 ms
SQL
복사
1차 AI 조언: 성공
제안된 개선안
•
선 집계 후 조인 방식
•
약 184만 건을 먼저 집계하여 867건으로 축소 후 조인
결과
•
실행시간: 2.2초(60% 개선)
•
하지만 여전히 184만 건의 Sort발생
2차 AI 조언: 실패(효과 없음)
•
추가적인 개선을 위해 1차 조언의 결과로 2차 AI 조언을 수행
•
AI는 여전히 남아있는 Sort 병목을 파악했지만, 해결책이 적절하지 않음
제안된 해결책
1.
(shop_id, ord_dtm, ord_amt) 복합 인덱스 생성
2.
TO_CHAR 대신 date_trunc 사용
실제 결과
•
인덱스 생성 후에도 실행계획 변화 없음
•
PostgreSQL 옵티마이저가 새 인덱스를 사용하지 않음
•
실행시간이 2.3초로 1차와 같음
발견된 문제점
1.
일관성 부족
•
같은 SQL에 대해 실행할 때마다 다른 튜닝 방안을 제시합니다.
2.
효과 검증 불과
•
실제 DB와 접속해서 처리하는 방식이 아니므로 개선안이 실제 효과가 있는지 AI가 자체 검증 불가
3.
고정된 프롬프트의 한계
•
프로그램에 내장된 고정 프롬프트로 질문하기 때문에, 상황에 따른 유연한 분석이 제한됨
책에서 제안하는 해결책
•
책에서는 이 방안의 최적 해법은 조인 횟수 감소와 함께 Hash Join 유도입니다.
결론: AI 시대, 튜너는 여전히 필요한가?
이번 사례를 보면 AI도 한계가 명확합니다. 하지만 공정하게 생각해보면, 인간 튜너도 비슷한 상황에 놓일 수 있습니다. 실제 DB에 접속해서 실행해보고 결과를 확인할 수 없는 환경이라면, 저 역시 AI와 비슷한 추론 과정을 거쳤을 가능성이 있습니다.
AI의 가능성과 한계
만약 AI가 실제 DB에 접속해서:
1.
SQL을 실행하고
2.
결과를 확인하고
3.
다시 개선안을 시도하고
4.
성능을 측정하는
이런 반복적인 실험을 자율적으로 수행할 수 있다면? 그것도 병렬으로! 아마도 전문 튜너보다 더 빠르게, 더 다양한 방법을 시도하며 최적화 방법을 찾아낼 수 있을 것입니다.
하지만 현실적으로 DB 작업은 너무 크리티컬합니다. 잘못된 인덱스 생성, 부적절한 쿼리 실행은 운영 시스템에 치명적인 영향을 줄 수 있습니다. 그래서 AI에게 DB에 대한 자율성을 무작정 맡기기는 어렵습니다.
특히 크리티컬하고 규모가 큰 시스템일수록, AI의 제안을 검증하고 승인하는 인간의 역할은 더욱 중요해질 것입니다.
그렇다면 어떻게 해야 할까?
결국 답은 AI와 인간의 협업입니다.
•
AI는 빠른 패턴 인식과 다양한 시도로 개선 방향을 제시하고
•
인간은 튜닝 지식을 바탕으로 AI의 제안을 검증하고 판단합니다
이제 SQL 튜너에게 필요한 것은 모든 SQL을 꼼꼼하게 분석하는 능력보다, AI를 효과적으로 활용하고 그 결과를 올바르게 검증할 수 있는 능력입니다. 실행계획을 읽고, 인덱스 동작을 이해하고, 병목을 찾아내는 기본 지식은 여전히 필수입니다.
AI가 답을 주더라도, 그게 맞는지 틀린지 판단하는 건 결국 사람의 몫이니까요.
권장사항: AI 조언은 강력한 도구이지만, 실무 적용 전 반드시 성능 검증과 영향도 분석이 필요합니다.
추신: Claude의 OpenClaw를 활용하면 원래 DBA 없이 운용하던 작은 시스템은 DBA를 뽑지 않아도 되겠다는 생각이 불현듯…
