테이블에 값들이 일정 시간 주기로 특정 값이 들어갑니다. 테스트 중이므로 현재 1초 주기로 렌덤값을 넣기로 했습니다.
그 테이블의 필요한 필드는 각각 data, date로 data는 real값이 들어가고 date는 datetime값이 들어갑니다.
1초마다 하나씩 쌓이는 데이터를 1분 간격으로 수집 된 데이터의 평균을 구해서 시간, 또는 특정 기간 동안 데이터가 어떻게 들어 왔는지를 구해야합니다.
어제 하루 동안 이것을 할 수 있는 SQL함수가 있는지 찾아봤지만 못찾게 되어 아침부터 UDF문서 찾아가면서 아래와 같은 함수를 만들었습니다.
create function [dbo].[GetDateStep](
@Align datetime, -- 기준이 되는 날짜
@Value datetime, -- 대상 날짜
@Step int -- 초단위의 그룹화 될 주기
)
returns int
as
begin
declare @ticks int
set @ticks = datediff(s, @Align, @Value) -- 기준 날짜와의 초단의 차이 구함
set @ticks = @ticks - (@ticks % @Step) -- Step값으로 시간 간격 교정
return @ticks -- 반환
end
위의 함수는 2000년 1월1일 값이 Align으로 고정되어 보내지고(함수 내에서 날짜를 생성하면 왠지 더 느릴거 같더군요;;;) 각 레코드의 date값이 Value에 넘어갑니다.
그리고 30초 주기의 값들의 평균들을 구하고 싶으면 세번째에 30이 들어가게 됩니다.
그래서 반환 되는 값들은 30초 단위의 2000년 1월 1일로 부터 지금까지 흐른 초가 반환됩니다.
그런데 이것이 생각 보다 빠르지 않습니다. 디비가 원격지에 있어서 트래픽이 훨신 둘어들어 40초 정도 걸릴 것이 4초로 출어 들긴 했지만 그래도 4초가 좀 깁니다.
저걸 이용하여 값을 뽑는 쿼리가
select avg([sdata]) as data, [dbo].[GetDateStep]({ts'2000-01-01 00:00:00'}, [date], 3600) as date from [testdata] where [nidx] = 1 group by [dbo].[GetDateStep]({ts'2000-01-01 00:00:00'}, [date], 3600)
저렇습니다. 혹시 더 빠르게 할 수 있는 방법이 있을까요?
앞의 필드 정의와 뒤의 그룹화 부분에 같은 것이 반복 되어 더 느려지는 것이 아닌가 싶은데 저걸 한번만 실행 되게 할 수 있을까요?
함수를 이용하지 않고도 할 수 있는 방법이 있을지 또한 알려주시면 감사하겠습니다. |