MySQL 미드레벨 기술면접
새 면접Q. MySQL에서 READ COMMITTED와 REPEATABLE READ 격리 수준의 차이점을 설명하고, 각 격리 수준에서 발생할 수 있는 동시성 문제와 실무에서 격리 수준을 선택하는 기준을 설명해주세요.
READ COMMITTED는 커밋된 데이터만 읽으며 Non-Repeatable Read가 발생할 수 있고, REPEATABLE READ는 트랜잭션 시작 시점의 스냅샷을 유지하여 일관된 읽기를 보장합니다. MySQL InnoDB의 REPEATABLE READ는 MVCC와 Next-Key Lock으로 Phantom Read도 방지하지만, 더 많은 Undo Log를 유지해야 합니다. 실무에서는 데이터 일관성이 중요한 금융 시스템은 REPEATABLE READ를, 높은 동시성이 필요한 서비스는 READ COMMITTED를 선택하며, 긴 트랜잭션에서는 READ COMMITTED가 Undo Log 증가를 방지할 수 있습니다.
- • READ COMMITTED는 커밋된 데이터만 읽고 Non-Repeatable Read 발생 가능
- • REPEATABLE READ는 트랜잭션 시작 시점 스냅샷 유지로 일관된 읽기 보장
- • InnoDB는 Next-Key Lock으로 Phantom Read도 방지
- • 격리 수준 선택은 일관성 요구사항과 동시성 요구사항의 트레이드오프
READ COMMITTED를 사용할 때 발생할 수 있는 Lost Update 문제를 어떻게 해결할 수 있나요?
Q. MySQL에서 카디널리티(Cardinality)가 낮은 컬럼에 인덱스를 생성하는 것이 비효율적인 이유를 설명하고, 성별이나 상태값 같은 저카디널리티 컬럼을 포함한 쿼리를 최적화하는 실무 전략을 설명해주세요.
카디널리티가 낮으면 인덱스를 통해 조회해도 많은 행을 스캔해야 하므로 랜덤 I/O가 증가하고, 옵티마이저가 풀 테이블 스캔을 선택할 가능성이 높습니다. 저카디널리티 컬럼은 단독 인덱스보다 고카디널리티 컬럼과 함께 복합 인덱스로 구성하거나, WHERE 조건에 고카디널리티 컬럼을 함께 사용하는 방식으로 최적화합니다. 또한 상태값이 특정 값으로 편향된 경우 부분 인덱스(Filtered Index)나 파티셔닝을 고려할 수 있으며, 통계 정보를 주기적으로 업데이트하여 옵티마이저가 올바른 실행 계획을 선택하도록 해야 합니다.
- • 저카디널리티 인덱스는 많은 행 스캔으로 랜덤 I/O 증가
- • 고카디널리티 컬럼과 복합 인덱스 구성으로 선택도 향상
- • 데이터 분포가 편향된 경우 부분 인덱스나 파티셔닝 고려
- • 통계 정보 업데이트로 옵티마이저의 올바른 판단 유도
복합 인덱스에서 저카디널리티 컬럼을 앞에 두는 것과 뒤에 두는 것의 차이는 무엇인가요?
Q. MySQL에서 EXISTS와 IN 연산자의 동작 방식 차이를 설명하고, 각각 어떤 상황에서 성능상 유리한지 서브쿼리와 조인 테이블의 크기 관점에서 설명해주세요.
EXISTS는 조건을 만족하는 첫 번째 행을 찾으면 즉시 TRUE를 반환하는 Short-Circuit 방식으로 동작하고, IN은 서브쿼리 결과 전체를 메모리에 로드한 후 매칭을 수행합니다. EXISTS는 외부 쿼리 각 행마다 서브쿼리를 실행하므로 서브쿼리 결과가 크고 외부 테이블이 작을 때 유리하며, IN은 서브쿼리를 한 번만 실행하므로 서브쿼리 결과가 작고 외부 테이블이 클 때 효율적입니다. 최신 MySQL 버전에서는 옵티마이저가 두 방식을 자동으로 최적화하여 세미 조인(Semi-Join)으로 변환하므로, 실행 계획을 확인하여 실제 동작을 파악하는 것이 중요합니다.
- • EXISTS는 Short-Circuit 방식으로 첫 매칭 시 즉시 반환
- • IN은 서브쿼리 전체 결과를 메모리에 로드
- • EXISTS는 서브쿼리 결과가 크고 외부 테이블이 작을 때 유리
- • 최신 MySQL은 세미 조인 최적화로 두 방식을 자동 변환
NOT EXISTS와 NOT IN의 NULL 처리 차이와 성능 차이를 설명해주세요.
Q. MySQL에서 대용량 히스토리 데이터를 저장할 때 단일 테이블로 관리하는 것과 별도의 히스토리 테이블로 분리하는 전략의 장단점을 비교하고, 실무에서 선택 기준과 구현 시 고려사항을 설명해주세요.
단일 테이블은 스키마가 단순하고 전체 이력 조회가 용이하지만, 테이블 크기 증가로 인덱스 성능이 저하되고 백업/복구 시간이 길어집니다. 히스토리 테이블 분리는 현재 데이터 조회 성능이 향상되고 파티셔닝이나 아카이빙이 용이하지만, 전체 이력 조회 시 UNION이 필요하고 스키마 변경 시 동기화가 필요합니다. 실무에서는 현재 데이터 조회가 빈번하고 히스토리 데이터가 급증하는 경우 분리를 선택하며, 분리 시에는 트리거나 애플리케이션 레벨에서 데이터 이동을 처리하고, 히스토리 테이블은 압축 스토리지 엔진이나 파티셔닝을 적용하여 저장 공간을 최적화합니다.
- • 단일 테이블은 단순하지만 크기 증가로 성능 저하
- • 히스토리 분리는 현재 데이터 조회 성능 향상 및 관리 용이
- • 전체 이력 조회 빈도와 데이터 증가율이 선택 기준
- • 분리 시 트리거/배치로 데이터 이동, 압축 및 파티셔닝 적용
히스토리 테이블로 데이터를 이동할 때 트랜잭션 일관성을 보장하는 방법은 무엇인가요?
Q. 프로덕션 환경에서 갑자기 Connection Pool이 고갈되어 신규 연결이 실패하는 상황이 발생했습니다. 이 문제의 주요 원인들과 각 원인을 진단하는 방법, 그리고 즉각적인 조치와 장기적인 해결 방안을 설명해주세요.
주요 원인으로는 커넥션 누수(애플리케이션에서 연결 미반환), 롱 러닝 쿼리로 인한 커넥션 점유, 갑작스런 트래픽 증가, 데드락이나 Lock 대기 등이 있습니다. 진단은 SHOW PROCESSLIST로 현재 실행 중인 쿼리와 상태 확인, information_schema.INNODB_TRX로 트랜잭션 상태 확인, 애플리케이션 로그에서 커넥션 타임아웃 패턴 분석으로 수행합니다. 즉각 조치로는 롱 러닝 쿼리 강제 종료(KILL), 커넥션 풀 크기 임시 증가, WAS 재시작으로 누수된 커넥션 해제를 수행하고, 장기 해결책으로는 커넥션 타임아웃 설정 최적화, 쿼리 성능 개선, 커넥션 풀 모니터링 강화, Read Replica 분산을 적용합니다.
- • 커넥션 누수, 롱 러닝 쿼리, 트래픽 증가, Lock 대기가 주요 원인
- • SHOW PROCESSLIST와 INNODB_TRX로 현재 상태 진단
- • 즉각 조치는 쿼리 종료, 풀 크기 증가, WAS 재시작
- • 장기 해결은 타임아웃 최적화, 쿼리 개선, 모니터링, 부하 분산
커넥션 풀의 최소/최대 크기와 타임아웃 값을 결정하는 기준은 무엇인가요?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!