MySQL 미드레벨 기술면접
새 면접Q. MySQL에서 인덱스가 많을수록 SELECT 성능은 좋아질 수 있지만, INSERT/UPDATE/DELETE 성능은 저하됩니다. 이러한 트레이드오프가 발생하는 이유를 설명하고, 실무에서 적절한 인덱스 개수를 결정하는 기준과 불필요한 인덱스를 식별하는 방법을 설명해주세요.
INSERT/UPDATE/DELETE 시 데이터 변경과 함께 모든 인덱스를 함께 갱신해야 하므로 쓰기 성능이 저하됩니다. 인덱스가 많을수록 B-Tree 구조 재조정과 페이지 분할이 빈번해져 오버헤드가 증가합니다. 실무에서는 쿼리 패턴 분석을 통해 자주 사용되는 WHERE, JOIN, ORDER BY 조건에만 인덱스를 생성하며, sys.schema_unused_indexes 뷰나 performance_schema를 활용해 사용되지 않는 인덱스를 주기적으로 모니터링하고 제거합니다. 일반적으로 테이블당 5~7개 이하의 인덱스를 권장하며, 쓰기 작업이 빈번한 OLTP 환경에서는 더욱 신중하게 결정해야 합니다.
- • 인덱스 갱신으로 인한 쓰기 오버헤드
- • B-Tree 재조정과 페이지 분할 비용
- • 쿼리 패턴 분석 기반 인덱스 설계
- • performance_schema를 통한 미사용 인덱스 식별
인덱스 힌트(USE INDEX, FORCE INDEX)를 사용해야 하는 상황과 그 위험성에 대해 설명해주세요.
Q. MySQL에서 긴 트랜잭션(Long Transaction)이 시스템에 미치는 부정적 영향을 설명하고, 프로덕션 환경에서 긴 트랜잭션을 모니터링하고 관리하는 방법, 그리고 애플리케이션 레벨에서 긴 트랜잭션을 방지하는 설계 패턴을 설명해주세요.
긴 트랜잭션은 Undo Log가 계속 쌓여 테이블스페이스가 비대해지고, 다른 트랜잭션들이 오래된 데이터 버전을 유지해야 해 MVCC 오버헤드가 증가합니다. 또한 잠금을 오래 유지하여 다른 트랜잭션의 대기 시간이 길어지고 데드락 가능성이 높아집니다. information_schema.innodb_trx 테이블에서 trx_started 시간을 확인하거나, performance_schema의 events_transactions_current를 모니터링하여 긴 트랜잭션을 식별할 수 있습니다. 애플리케이션에서는 트랜잭션 범위를 최소화하고, 외부 API 호출이나 파일 I/O는 트랜잭션 밖에서 처리하며, 대량 작업은 배치 단위로 커밋하는 패턴을 사용합니다.
- • Undo Log 증가와 테이블스페이스 비대화
- • MVCC 오버헤드와 잠금 경합 증가
- • information_schema.innodb_trx를 통한 모니터링
- • 트랜잭션 범위 최소화 설계 패턴
autocommit=0 설정과 명시적 트랜잭션 사용의 차이점과 각각의 장단점을 설명해주세요.
Q. MySQL에서 ORDER BY 절이 포함된 쿼리를 최적화할 때 인덱스를 활용하는 방법과 Using filesort가 발생하는 경우를 설명하고, filesort를 피할 수 없는 상황에서 성능을 개선하는 방법을 설명해주세요.
ORDER BY 절의 컬럼이 인덱스에 포함되어 있고 인덱스 순서와 정렬 방향이 일치하면 인덱스를 사용해 정렬 없이 결과를 반환할 수 있습니다. 하지만 ORDER BY 컬럼이 인덱스에 없거나, WHERE 조건과 ORDER BY 컬럼이 다른 인덱스를 사용하거나, 정렬 방향이 혼합된 경우 Using filesort가 발생합니다. filesort는 sort_buffer_size 메모리에서 정렬을 수행하며, 데이터가 크면 디스크 임시 파일을 사용해 성능이 저하됩니다. 개선 방법으로는 WHERE와 ORDER BY를 함께 고려한 복합 인덱스 생성, sort_buffer_size 증가, 또는 LIMIT를 사용해 정렬 대상 레코드 수를 줄이는 방법이 있습니다.
- • 인덱스 순서와 정렬 방향 일치 시 filesort 회피
- • WHERE와 ORDER BY 조건을 고려한 복합 인덱스 설계
- • sort_buffer_size와 디스크 임시 파일 사용
- • LIMIT를 통한 정렬 대상 감소
ORDER BY와 GROUP BY가 함께 사용될 때 인덱스 최적화 전략은 어떻게 달라지나요?
Q. MySQL에서 ENUM 타입과 VARCHAR 타입을 선택할 때 고려해야 할 사항을 저장 공간, 성능, 유지보수 관점에서 비교 설명하고, 각각 어떤 상황에서 적합한지 실무 예시를 들어 설명해주세요.
ENUM은 내부적으로 정수로 저장되어 1~2바이트만 사용하므로 저장 공간이 효율적이고, 정수 비교로 인해 조회 성능이 빠릅니다. 하지만 값 추가나 수정 시 ALTER TABLE이 필요하고, 순서 변경이나 값 삭제가 어려워 유지보수성이 떨어집니다. VARCHAR는 문자열 그대로 저장되어 공간을 더 사용하지만, 애플리케이션에서 자유롭게 값을 관리할 수 있어 유연합니다. 실무에서 상태값이나 카테고리처럼 변경이 거의 없고 선택지가 명확한 경우 ENUM을 사용하고, 자주 변경되거나 다국어 지원이 필요한 경우 VARCHAR와 별도 코드 테이블을 사용하는 것이 적합합니다.
- • ENUM의 정수 저장과 공간 효율성
- • ALTER TABLE 필요성과 유지보수 제약
- • VARCHAR의 유연성과 코드 테이블 패턴
- • 변경 빈도에 따른 선택 기준
SET 타입은 ENUM과 어떻게 다르며, 어떤 상황에서 사용하는 것이 적합한가요?
Q. 프로덕션 환경에서 특정 시간대에 MySQL의 CPU 사용률이 급증하는 문제가 발생했습니다. 이 문제의 원인을 진단하기 위해 확인해야 할 MySQL 메트릭과 쿼리들, 그리고 원인별 해결 방안을 체계적으로 설명해주세요.
먼저 performance_schema의 events_statements_summary_by_digest를 확인해 CPU 시간이 긴 쿼리를 식별하고, SHOW PROCESSLIST로 현재 실행 중인 쿼리와 상태를 확인합니다. sys.statements_with_runtimes_in_95th_percentile로 지연이 큰 쿼리를 분석하고, SHOW ENGINE INNODB STATUS로 잠금 경합이나 세마포어 대기 상황을 확인합니다. 원인별로 1) 비효율적인 쿼리는 인덱스 추가나 쿼리 리팩토링, 2) 동시 접속 급증은 Connection Pool 조정이나 Read Replica 추가, 3) 배치 작업 충돌은 스케줄 분산, 4) 통계 정보 오래됨은 ANALYZE TABLE 실행으로 해결합니다. 또한 innodb_buffer_pool_size와 thread_cache_size 같은 파라미터 튜닝도 고려합니다.
- • performance_schema를 통한 쿼리 레벨 분석
- • SHOW PROCESSLIST와 SHOW ENGINE INNODB STATUS 활용
- • 쿼리 최적화, 커넥션 관리, 배치 스케줄 조정
- • 통계 정보 갱신과 파라미터 튜닝
MySQL의 Query Cache가 deprecated된 이유와 대안으로 어떤 캐싱 전략을 사용할 수 있는지 설명해주세요.
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!