[PostgreSQL] 통계 쿼리 조건절 컬럼 가공을 제거 해서 인덱스를 타게 하는 방법
어떤 테이블에 insert_dt 컬럼에 인덱스가 있어도 substring(insert_dt, 1, 6)처럼 컬럼을 가공하면 데이터베이스가 인덱스를 사용하지 못하고 전체 테이블 스캔(Full Table Scan)을 하게 됩니다.
인덱스를 타게 하려면 컬럼은 그대로 두고, 비교하는 대상을 데이터 형식(‘20261006000132’)에 맞춰 변경해야 합니다.
가장 성능이 좋고 올바른 해결 방법 2가지를 소개해 드립니다.
1. BETWEEN 연산자 사용
조회하려는 월의 시작 일시부터 마지막 일시까지의 범위를 BETWEEN으로 지정하는 방법입니다. 컬럼을 변형하지 않으므로 인덱스를 완벽하게 활용합니다.
예를 들어 2026년 10월 데이터를 조회한다면 아래와 같이 작성합니다.
SELECT COUNT(*)
FROM 테이블명
WHERE insert_dt BETWEEN '20261001000000' AND '20261031235959';
- 장점: 표준 SQL 방식이며 성능이 가장 확실합니다.
- 주의점: 월별로 일수(30일, 31일, 28일 등)가 다르므로 데이터베이스 함수나 애플리케이션(Java, Python 등) 단에서 조회 조건의 ‘마지막 날짜’를 계산해서 넘겨주어야 합니다.
2. 크거나 같다(>=)와 작다(<) 연산자 사용
마지막 날짜를 계산하기 번거롭다면, 다음 달 1일 0시 미만으로 조건을 거는 방식입니다. 날짜 계산 오류를 방지할 수 있어 실무에서 많이 쓰입니다.
SELECT COUNT(*)
FROM 테이블명
WHERE insert_dt >= '20261001000000'
AND insert_dt < '20261101000000'; -- 다음 달 1일 미만
SELECT COUNT(*)
FROM 테이블명
WHERE AND insert_dt >= SUBSTRING(p_stat_dt, 1, 6) || '01' -- 당월 1일 (예: '20261001')
AND insert_dt < TO_CHAR(TO_DATE(SUBSTRING(p_stat_dt, 1, 6), 'YYYYMM') + INTERVAL '1 MONTH', 'YYYYMMDD') -- 다음달 1일 미만 (예: '20261101')
- 장점: 월말일이 30일인지 31일인지 신경 쓰지 않아도 되므로 쿼리 작성이 더 직관적입니다. 당연히 인덱스도 잘 작동합니다.
[연관자료]




