MySQL 미드레벨 기술면접
새 면접Q. MySQL에서 Covering Index(커버링 인덱스)의 개념과 동작 원리를 설명하고, 어떤 상황에서 성능 향상을 기대할 수 있는지 실무 예시와 함께 설명해주세요.
Covering Index는 쿼리에서 필요한 모든 컬럼이 인덱스에 포함되어 있어 테이블 접근 없이 인덱스만으로 쿼리를 처리할 수 있는 인덱스입니다. EXPLAIN 결과에서 Extra 항목에 'Using index'로 표시되며, 디스크 I/O를 크게 줄여 성능을 향상시킵니다. SELECT 쿼리의 모든 컬럼이 인덱스에 포함되어 있을 때 발생하며, 예를 들어 복합 인덱스 (user_id, created_at, status)가 있을 때 'SELECT status FROM orders WHERE user_id = 1 AND created_at > DATE'와 같은 쿼리는 테이블 접근 없이 인덱스만으로 처리됩니다. 특히 대량의 데이터를 조회할 때 랜덤 액세스를 제거하여 성능이 수십 배 향상될 수 있습니다.
- • 쿼리에 필요한 모든 컬럼이 인덱스에 포함되어 테이블 접근이 불필요한 상태
- • EXPLAIN에서 'Using index'로 표시되며 디스크 I/O를 크게 감소
- • 복합 인덱스 설계 시 SELECT 절의 컬럼까지 고려하여 커버링 인덱스 구성 가능
- • 랜덤 액세스를 제거하여 대량 조회 시 성능 향상 효과가 큼
커버링 인덱스를 만들기 위해 불필요한 컬럼까지 인덱스에 추가하는 것이 항상 좋은 전략인가요? 인덱스 크기 증가에 따른 트레이드오프는 무엇인가요?
Q. MySQL InnoDB의 Undo Log와 Redo Log의 역할과 차이점을 설명하고, 이 두 로그가 트랜잭션의 ACID 속성 중 어떤 부분을 보장하는지 설명해주세요.
Undo Log는 트랜잭션 롤백과 MVCC 구현을 위해 변경 전 데이터를 저장하는 로그로, 트랜잭션의 Atomicity(원자성)와 Isolation(격리성)을 보장합니다. Redo Log는 데이터베이스 크래시 복구를 위해 변경 후 데이터를 기록하는 WAL(Write-Ahead Logging) 방식의 로그로, Durability(지속성)를 보장합니다. Undo Log는 트랜잭션 롤백 시 이전 상태로 복원하고, 다른 트랜잭션이 커밋되지 않은 데이터를 읽을 때 이전 버전을 제공합니다. Redo Log는 버퍼 풀의 변경사항을 먼저 기록한 후 실제 데이터 파일에 비동기로 반영하여, 시스템 장애 시 커밋된 트랜잭션을 복구할 수 있게 합니다. 두 로그는 상호보완적으로 작동하여 트랜잭션의 안정성과 성능을 동시에 달성합니다.
- • Undo Log는 변경 전 데이터를 저장하여 롤백과 MVCC를 지원하며 Atomicity와 Isolation 보장
- • Redo Log는 변경 후 데이터를 WAL 방식으로 기록하여 크래시 복구를 지원하며 Durability 보장
- • Undo Log는 트랜잭션 롤백과 일관된 읽기를 위한 이전 버전 제공에 사용
- • Redo Log는 버퍼 풀 변경사항을 순차적으로 기록하여 성능과 안정성을 동시에 확보
innodb_flush_log_at_trx_commit 설정값(0, 1, 2)에 따라 Redo Log의 동작이 어떻게 달라지며, 각 설정의 성능과 안정성 트레이드오프는 무엇인가요?
Q. MySQL에서 GROUP BY 쿼리를 최적화하는 방법들을 설명하고, Loose Index Scan과 Tight Index Scan의 차이점 및 각각이 적용되는 조건을 설명해주세요.
GROUP BY 최적화는 인덱스 활용이 핵심이며, Loose Index Scan과 Tight Index Scan 두 가지 방식으로 동작합니다. Loose Index Scan은 인덱스의 각 그룹 대표값만 읽어서 처리하는 방식으로, EXPLAIN에서 'Using index for group-by'로 표시되며, WHERE 조건 없이 GROUP BY만 있거나 MIN/MAX 같은 집계함수를 사용할 때 적용됩니다. Tight Index Scan은 인덱스의 모든 행을 순차적으로 읽어 그룹핑하는 방식으로, WHERE 조건과 GROUP BY가 함께 있을 때 주로 사용됩니다. 최적화를 위해서는 GROUP BY 컬럼에 인덱스를 생성하고, 복합 인덱스의 경우 GROUP BY 컬럼 순서와 인덱스 컬럼 순서를 일치시켜야 하며, 불필요한 DISTINCT나 ORDER BY는 제거하는 것이 좋습니다.
- • Loose Index Scan은 그룹 대표값만 읽어 처리하며 'Using index for group-by'로 표시
- • Tight Index Scan은 인덱스의 모든 행을 읽어 그룹핑하는 방식
- • GROUP BY 컬럼에 적절한 인덱스 생성과 컬럼 순서 일치가 중요
- • MIN/MAX 집계함수와 WHERE 조건 없는 경우 Loose Index Scan 적용 가능
GROUP BY 쿼리에서 filesort가 발생하는 경우와 이를 방지하기 위한 전략은 무엇이며, 임시 테이블 사용을 피하는 방법은 무엇인가요?
Q. MySQL에서 정규화(Normalization)와 비정규화(Denormalization)의 개념을 설명하고, 실무에서 비정규화를 선택해야 하는 상황과 그에 따른 트레이드오프를 구체적인 예시와 함께 설명해주세요.
정규화는 데이터 중복을 제거하고 무결성을 보장하기 위해 테이블을 분리하는 과정이며, 비정규화는 성능 향상을 위해 의도적으로 중복을 허용하는 설계 기법입니다. 정규화는 데이터 일관성과 저장 공간 절약에 유리하지만 JOIN 연산이 증가하여 조회 성능이 저하될 수 있습니다. 비정규화는 읽기 중심의 서비스에서 자주 조회되는 데이터를 중복 저장하여 JOIN을 줄이고 성능을 향상시킵니다. 예를 들어, 주문 테이블에 사용자 이름을 중복 저장하면 사용자 테이블과의 JOIN 없이 주문 목록을 빠르게 조회할 수 있지만, 사용자 이름 변경 시 모든 주문 레코드를 업데이트해야 하는 부담이 발생합니다. 실무에서는 읽기/쓰기 비율, 데이터 변경 빈도, 쿼리 패턴을 고려하여 선택적으로 비정규화를 적용합니다.
- • 정규화는 중복 제거와 무결성 보장, 비정규화는 성능 향상을 위한 의도적 중복 허용
- • 읽기 중심 서비스에서 자주 조회되는 데이터에 비정규화 적용
- • 비정규화 시 데이터 일관성 유지를 위한 추가 로직 필요
- • 읽기/쓰기 비율과 데이터 변경 빈도를 고려한 선택적 적용이 중요
비정규화된 데이터의 일관성을 유지하기 위한 전략에는 어떤 것들이 있으며, 애플리케이션 레벨과 데이터베이스 레벨에서 각각 어떻게 구현할 수 있나요?
Q. MySQL의 Slow Query Log를 활용한 성능 분석 방법을 설명하고, 슬로우 쿼리 발견 후 실제 최적화 과정에서 확인해야 할 주요 지표들과 분석 도구들을 설명해주세요.
Slow Query Log는 설정한 시간(long_query_time) 이상 실행된 쿼리를 기록하여 성능 병목을 찾는 핵심 도구입니다. 슬로우 쿼리 발견 후에는 먼저 EXPLAIN을 통해 실행 계획을 분석하고, type, rows, Extra 항목을 확인하여 풀 테이블 스캔이나 filesort 여부를 파악합니다. SHOW PROFILE이나 Performance Schema를 사용하여 쿼리 실행의 각 단계별 시간을 측정하고, 어느 부분에서 시간이 소요되는지 정확히 파악합니다. pt-query-digest 같은 도구로 슬로우 쿼리 로그를 집계 분석하여 가장 빈번하거나 총 실행 시간이 긴 쿼리를 우선순위로 선정합니다. 최적화 시에는 인덱스 추가, 쿼리 재작성, 파티셔닝, 캐싱 등 다양한 기법을 적용하고, 최적화 전후 성능을 비교 측정하여 효과를 검증합니다.
- • long_query_time 설정으로 슬로우 쿼리를 로그에 기록하고 성능 병목 발견
- • EXPLAIN으로 실행 계획 분석, Performance Schema로 단계별 시간 측정
- • pt-query-digest로 슬로우 쿼리 집계 분석 및 우선순위 선정
- • 인덱스, 쿼리 재작성 등 최적화 적용 후 성능 비교 검증 필수
프로덕션 환경에서 Slow Query Log를 활성화할 때 고려해야 할 성능 오버헤드와 로그 관리 전략은 무엇이며, 어떻게 안전하게 운영할 수 있나요?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!