성능 튜닝은 코드를 많이 바꾸는 작업이 아니라 같은 조건에서 병목을 측정하고 가장 작은 변경의 효과를 확인하는 과정이다. 이 글은 MariaDB 10.11의 별도 실습 DB에서 날짜 조건 쿼리를 비교하는 절차를 다룬다.
ANALYZE는 쿼리를 실제 실행한다. 변경 쿼리나 큰 운영 테이블에 바로 사용하지 말고 읽기 전용 실습 환경에서 영향부터 확인한다.
1. 재현용 데이터베이스
USE testdb;
SHOW INDEX FROM orders;
SELECT COUNT(*) AS order_count FROM orders;
실제 비교에서는 충분한 표본과 현실적인 분포가 필요하다. 데이터 건수, MariaDB 버전, 버퍼 상태와 실행 시각을 결과와 함께 기록한다.
2. 비교할 두 쿼리
-- 컬럼에 함수를 적용한 조건
SELECT order_id, order_no
FROM orders
WHERE status = 'SHIPPED'
AND DATE(ordered_at) = '2026-08-01';
-- 같은 날짜를 범위로 표현한 조건
SELECT order_id, order_no
FROM orders
WHERE status = 'SHIPPED'
AND ordered_at >= '2026-08-01 00:00:00'
AND ordered_at < '2026-08-02 00:00:00';
두 쿼리의 결과 집합이 정말 같은지 먼저 확인한다. 시간대 변환이나 nullable 컬럼이 들어가면 단순 변환만으로 의미가 달라질 수 있다.
3. 실행 계획과 실제 통계 확인
EXPLAIN FORMAT=JSON
SELECT order_id, order_no
FROM orders
WHERE status = 'SHIPPED'
AND ordered_at >= '2026-08-01 00:00:00'
AND ordered_at < '2026-08-02 00:00:00';
ANALYZE FORMAT=JSON
SELECT order_id, order_no
FROM orders
WHERE status = 'SHIPPED'
AND ordered_at >= '2026-08-01 00:00:00'
AND ordered_at < '2026-08-02 00:00:00';
EXPLAIN은 옵티마이저 계획을 보여주고 ANALYZE는 쿼리를 실행해 실제 통계를 더한다. 접근 방식, 선택한 key, 예상·실제 행 수와 필터링 차이를 확인한다.
4. 전후 기록표
환경: MariaDB 10.6.26 / 127.0.0.1:3306 / testdb
테이블 행 수: 9
조건에 일치한 행 수: 1 (status='SHIPPED', ordered_at 2026-08-01)
쿼리 A key / rows / 실제 시간:
쿼리 B key / rows / 실제 시간:
반복 횟수:
콜드·웜 캐시 구분:
결과 집합 동일 여부:
최종 판단:
한 번 실행한 시간만으로 결론을 내리지 않는다. 다른 부하를 통제하고 여러 번 반복하며, 중앙값과 변동 폭을 함께 본다.
5. 인덱스 추가 전 확인
- 해당 쿼리의 호출 빈도와 전체 지연 기여도가 큰가
- 기존 복합 인덱스로 해결할 수 있는가
- 새 인덱스가 INSERT·UPDATE와 저장 공간에 주는 영향은 무엇인가
- 선택도가 낮아 옵티마이저가 사용하지 않을 가능성이 있는가
- 운영 DDL의 잠금과 롤백 계획을 확인했는가
6. 튜닝이 실패하는 패턴
CPU가 높다는 이유로 캐시를 먼저 붙이거나, 느린 요청 하나만 보고 서버 크기를 올리거나, 실행 계획 없이 인덱스를 계속 추가하면 원인을 가릴 수 있다. 요청 시간에서 PHP, DB, 외부 API가 차지하는 구간을 먼저 나누고 가장 큰 병목부터 다룬다.
정리: 쿼리 튜닝은 결과 동일성을 확인하고 EXPLAIN과 실제 실행 통계를 기록한 뒤, 변경 전후를 같은 조건에서 반복 비교하는 작업이다.
댓글 0