문제 상황
최근 운영 환경에서 단순한 JOIN 쿼리 하나가 비정상적으로 느리게 동작하는 현상을 경험했습니다.
인덱스가 정상적으로 걸려 있음에도 불구하고, 실행 시간이 수십 초까지 치솟는 상황이었습니다.
분석 끝에 원인은 테이블 간 Collation 불일치였고, utf8mb3 와 utf8mb4 의 차이가 문제를 일으키고 있었습니다.
이번 글에서는 그 원인과 해결 방법을 정리합니다.
SELECT
dh.msg_group_id AS msgGroupId,
dh.reg_user_id AS regUserId,
um.msg_subject AS msgSubject,
um.msg_content AS msgContent,
um.recv_group_cd AS recvGroupCd,
um.send_media_cd AS sendMediaCd,
um.send_datetime AS sendDatetime,
dh.reg_datetime AS regDatetime,
um.send_method_cd AS sendMethodCd
FROM msg_send_detail_history dh
JOIN msg_send_master um
ON dh.msg_group_id = um.msg_group_id
WHERE dh.user_seq = :userSeq
AND um.send_media_cd <> 'at'
AND dh.reg_datetime BETWEEN :startDateTime AND :endDateTime
ORDER BY dh.reg_datetime DESC;
데이터건수 : [4031건] 쿼리 동작하는데 30초가 넘게 걸림
원인분석
쿼리 실행 계획(EXPLAIN)을 확인해본 결과, 두 테이블 모두 msg_group_id 에 인덱스가 걸려 있음에도 불구하고
Index Merge / Full Table Scan 이 발생하고 있었습니다.
확인해보니 문제의 원인은 두 테이블의 Collation 불일치였습니다.
- msg_send_detail_history.msg_group_id → utf8mb4_general_ci
- msg_send_master.msg_group_id → utf8mb3_general_ci
즉, 두 테이블의 문자열 컬럼이 서로 다른 Collation 을 사용하고 있었고,
MySQL은 JOIN 시 양쪽 값을 일시적으로 변환(Collation Casting) 해야 했습니다.
이 변환 과정 때문에 인덱스를 정상적으로 활용하지 못했고, 결국 성능 저하로 이어졌습니다.
해결방법
ALTER TABLE msg_send_master
MODIFY msg_group_id VARCHAR(50)
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;
- 또는 반대로 msg_send_detail_history 도 동일하게 맞춰줍니다.
- 서비스 전체 표준 Collation 지정
- 새로 생성되는 테이블은 반드시 utf8mb4_general_ci(혹은 utf8mb4_unicode_ci) 로 고정.
- DDL 작성 시 명시적으로 Character Set & Collation 선언.
- 쿼리 점검msg_group_id 인덱스를 정상적으로 타면서 조회 속도가 획기적으로 개선되었습니다.
- Collation 불일치가 해소된 이후 EXPLAIN을 다시 확인하면, msg_group_id 인덱스를 정상적으로 타면서 조회 속도가 획기적으로 개선되었습니다.
마무리
이번 사례는 단순한 쿼리였지만, Collation 불일치로 인해 인덱스가 무용지물이 되는 경험을 했습니다.
“쿼리가 느리다” → “인덱스 확인” 에서 끝나는 게 아니라,
“스키마 레벨에서 Collation/Charset 불일치가 있는지” 까지도 점검하는 습관이 필요하다는 교훈을 얻었습니다.
'Database' 카테고리의 다른 글
| ERROR 1231 (42000): Variable 'sql_mode' can't be set to the value of 'NO_AUTO_CREATE_USER' (0) | 2023.11.16 |
|---|---|
| Command 'mongo' not found 몽고디비 (0) | 2023.05.18 |
| MongoDB active failed 문제( result- exit-code) (0) | 2023.05.10 |
| MongoDB 설치시 Command not found: mongo (3) | 2023.04.12 |
| SQL 의 COALESCE 함수 사용법 (0) | 2023.04.07 |