2016-10-11 2 views
0

first_seen (datetime), last_seen (datetime) 및 severity (정수) 인 이벤트가있는 테이블이 있습니다.간격이있는 PostgreSQL 질의 시간 목록 최적화

나는 신중로 15 분 간격으로 활성 얼마나 많은 이벤트 찾으려고 노력 해요 :

WITH intervals AS 
    (
     SELECT 
     '2016-08-02 00:00:00'::TIMESTAMP 
      + (n||' minutes')::INTERVAL AS start_time, 
     '2016-08-02 00:00:00'::TIMESTAMP 
      + ((n + 15)||' minutes')::INTERVAL AS end_time 
     FROM generate_series(0, 24 * 60, 15) n 
) 
SELECT 
    start_time, 
    (SELECT count(*) FROM event 
    WHERE first_seen < end_time AND last_seen > start_time 
     AND severity = 5) red, 
    (SELECT count(*) FROM event 
    WHERE first_seen < end_time AND last_seen > start_time 
     AND severity = 4) orange, 
    (SELECT count(*) FROM event 
    WHERE first_seen < end_time AND last_seen > start_time 
     AND severity = 3) yellow 
FROM intervals; 

또한 (first_seen, last_seen, severity)에 인덱스를 가지고있다.
내 문제는 너무 느린 것 같습니다.
테이블에는 약 10 만 개의 행이 있으며 100 개의 간격에는 10 초가 걸립니다. 인덱스 스캔 속도가 너무 느립니다.

어떤 아이디어가이 쿼리를 최적화하는 방법?

답변

1

가장 좋은 것은 subselects 제거하는 것입니다. 다음 (테스트되지 않은, 그것은 포함 할 수 있도록 오류)와 같은

시도 뭔가 :

WITH intervals AS 
    (
     SELECT 
     '2016-08-02 00:00:00'::TIMESTAMP 
      + (n||' minutes')::INTERVAL AS start_time, 
     '2016-08-02 00:00:00'::TIMESTAMP 
      + ((n + 15)||' minutes')::INTERVAL AS end_time 
     FROM generate_series(0, 24 * 60, 15) n 
) 
SELECT 
    start_time, 
    sum(CASE WHEN severity = 5 THEN 1 ELSE 0 END) red, 
    sum(CASE WHEN severity = 4 THEN 1 ELSE 0 END) orange, 
    sum(CASE WHEN severity = 3 THEN 1 ELSE 0 END) yellow 
FROM event 
    RIGHT OUTER JOIN intervals 
     ON first_seen < end_time AND last_seen > start_time 
GROUP BY start_time; 
ORDER BY start_time; 

당신은 first_seenlast_seen에 두 개의 인덱스가 일을 빠르게 할 수 있습니다. 다중 열 인덱스는 도움이되지 않습니다.

+1

참고 : generate_series는()도, 타임 스탬프와 함께 작동 :'간격 ( SELECT GS AS START_TIME , GS + '15 분 'generate_series FROM AS END_TIME ('2016년 8월 2일 0시 0분 0초 AS ' :: TIMESTAMP , '2016-08-03 00:00:00':: TIMESTAMP ,15 분 ':: INTERVAL) gs ' – joop

+1

예. 혼란을 줄이기 위해 그 부분을 그대로 두었습니다. –

+0

와우, 2 배 빠릅니다. 고마워. – windravenii