POSQTGRESQL에 시간 데이터를 넣고 호출하는데 있어 어느 타입이 더 효율적일까?
HH:MM의 시간 포멧을 놓고 각각 CHAR, NUMERIC, TIME 세 가지 타입에 넣어 실험해보았다. POSQTGRESQL은 13 버전을 이용하였다.
조건 1.
,ALARM_TIME char(4)
SQL
복사
첫 번째 조건은 HH:MM의 시간 포멧을 네 개의 CHAR로 넣는 형태이다. 04:30의 경우 ‘0430’으로 들어간다.
조건 2.
,ALARM_HOUR numeric(2, 0) NOT NULL
CHECK (0 <= ALARM_HOUR and ALARM_HOUR <= 23)
,ALARM_MIN numeric(2, 0) NOT NULL
CHECK (0 <= ALARM_MIN and ALARM_MIN <= 59)
SQL
복사
두 번째 조건은 두 개의 NUMERIC 컬럼에 시간을 나누어 담는 형태이다. 04:30의 경우 앞의 컬럼에 ‘4’가, 뒤에 컬럼에 ‘30’이 각각 나뉘어 들어간다.
조건 3.
,ALARM_TIME time NOT NULL
SQL
복사
POSQTGRESQL에서 지원하는 TIME 데이터 타입을 그대로 사용하는 형태이다. 04:30의 경우 ‘04:30:00’으로 저장이 된다. 뒤에는 반드시 ‘00’일 것을 전제하여 호출 시에는 ‘04:30:00’와 정확히 매칭되는 결과물을 가져온다.
동일한 조건으로 구성하되, 보다 사실적인 환경 구성을 위해 USER_ID 컬럼과 MODIFIED_TIME 컬럼을 추가하였다.
각각 5000개의 row를 무작위로 생성해 넣은 뒤 00시 00분 부터 23시 59분까지 전체의 시간을 질의하여 가져오는 시간을 가져온다. 한번 싸이클에 1440회의 질의가 발생한다. 각각의 조건에 대해 10번씩 시도하여, 전체 평균을 구하도록 하겠다.
결과
전체 결과
조건 1 average: 26.126652979850768
조건 2 average: 28.070282173156738
조건 3 average: 26.070684099197386
눈에 띄는 것은 ‘조건 2’에서 시간이 다른 조건에 비해 2초가 늦어지는 점이다. 조회하는 컬럼이 두 개라서 시간이 지연되는 것으로 짐작된다. 흥미로운 점은, 캐릭터 4만을 사용하는 조건 1보다도 TIME 데이터 타입을 사용하는 조건 3이 약 0.5초 정도 앞선다는 것이다.
이번에는 row의 개수를 십만개로 늘려 적용해보았다. 반복 횟수 역시 각각 20번으로 늘렸다.
전체결과
조건 1 average: 49.10826389789581
조건 2 average: 64.23751240968704
조건 3 average: 44.287118303775785
5천개에서 10만개로 ‘스므배’ 정도로 분량을 늘리니, 조회 시간이 약 2배 정도 늘어났다. 분량이 늘어나면서 조회 시간에 대한 차이가 도드라지는데, 조건 1에 비해 조건 2가 15초나 더 늘어났다. 흥미로운 점은 조건 1에 비해 조건 3이 약 5초 정도 더 빠르다는 점이다.
결론1. 포스트그래스큐엘이 ‘시간 컬럼’은 알아서 최적화를 잘 해주니, 시간 관련해서는 시간 관련 데이터 타입을 사용하자.
결론2. 컬럼이 10만개 이상 쌓이는 환경이 아닌 이상, 실제 조회 시간에 대한 차이가 얼마 나지 않는다. 자료형 간의 차이는 실제로 소소한 범위이다.