[SQL 튜닝] SQL 문 단순 수정을 통한 튜닝(3): 형변환으로 인덱스를 활용하지 못하는 나쁜 SQL 문

최건우·2023년 9월 29일
0

데이터베이스/SQL

목록 보기
11/13

1. 형변환으로 인덱스를 활용하지 못하는 나쁜 SQL 문

1-1. 현황 분석

급여 테이블에서 현재 유효한 급여 정보만 조회하고자 사용여부 컬럼의 값이 1인 데이터를 출력하는 쿼리가 있다고 하자.

튜닝 전 실행 계획은 다음과 같다.

type 항목이 index이므로 인덱스 풀 스캔 방식으로 수행하되,Key 항목의 I\_사용여부 인덱스를 사용함을 알 수 있다.
또한 filtered 항목이 10.00이므로 스토리지 엔진에서 가져온 데이터 중 10%를 추출해서 최종 데이터를 출력할 것임을 알 수 있다(단, filtered 항목의 값은 정확히 10%가 아니라 통계 정보로부터 예측된 값임을 주의한다).



1-2. 튜닝 수행

먼저 사용여부 컬럼의 데이터 건수를 확인해 보자. 해당 컬럼은 0, 1로 이루어져있음을 확인할 수 있다.

이번에는 해당 테이블에 구성된 인덱스 현황을 살펴보자.

Key_name 항목에 튜닝 전 실행 계획에 나왔던 I_사용여부 인덱스가 있다. 해당 인덱스는 사용여부 컬럼으로 구성된다.
SQL 문에서 사용여부 컬럼이 인덱스로 구성되었고, WHERE 절의 조건문으로 작성되었음에도 불구하고 인덱스 풀 스캔으로 수행되는 이유는 무엇일까? 이를 확인하기 위해 테이블 구조를 다시 살펴봐야 한다.


사용여부 컬럼의 데이터 유형이 문자열임을 알 수 있다. 따라서, 튜닝 전 SQL 문의 WHERE 절은 사용여부 = 1과 같이 숫자 유형으로 써서 데이터에 접근했으므로, DBMS 내부에서 형변환이 발생했던 것이다. 그 결과 인덱스를 제대로 활용하지 못하고 전체 데이터를 스캔한 것이다. 따라서 형변환이 발생하지 않도록 SQL 문을 조정해야 한다.



1-3. 튜닝 결과

형변환을 제거한 SQL문과 그 실행 결과는 다음과 같다. 실행 시간은 1.76초에서 0.03초로 향상되었다.

튜닝 후 실행 계획을 살펴보면, 튜닝 전과 달리 사용여부 = '1' 조건절이 스토리지 엔진에서 전달되어 필요한 데이터만 가져왔음을 알 수 있다.

위 문제를 해결하는 또 다른 방법으로는 사용여부 컬럼의 데이터 유형을 변경하는 방법이 있다. CHAR(1)에서 INT로 변경하기만 하면 SQL 문을 수정하지 않고도 그대로 인덱스를 사용할 수 있다. 그러나 테이블의 DDL 문을 수행해야 하는 부담DDL 수행 시의 데이터 잠김(data lock) 현상으로 인해 동시성 저하 문제가 발생할 수 있다.

위 사례를 통해 데이터 유형에 맞게 컬럼을 활용해야 내부적인 형변환이 발생하지 않으며, 형변환의 영향으로 의도한 인덱스를 제대로 사용하지 못할 수 있음을 기억하자.





profile
부족한 경험을 채우기 위한 나만의 기록 공간

0개의 댓글