2014-07-11 1 views
2

나는 다음과 같은 쿼리를 가지고 :PostgreSQL을 - 다른 컬럼의 프록시에 의해 인덱싱 된 열을 쿼리

SELECT SUM(data), foreign_key 
FROM (SELECT * 
    FROM really_big_table 
    ORDER BY auto_incremented_id DESC 
    LIMIT reasonable_number) 
WHERE inserted_timestamp > now() - INTERVAL '1 hour' 
GROUP BY foreign_key 

성공적으로 inserted_timestamp를 통해 순차적으로 스캔을 실행 피한다하지만,보다 더가있는 경우는 완전히 실패합니다이 쿼리 검색해야하는 합리적인 수의 행 inserted_timestamp는 인덱싱되지 않았으므로 auto_incremented_id와 동일한 순서를 따르므로 새 인덱스를 만드는 한 시간의 가동 중단없이이 쿼리를 훨씬 효율적으로 만들 수 있다고 생각합니다.

나는 같은 것을 할 싶습니다 :

SELECT SUM(data), foreign_key 
FROM really_big_table 
ORDER BY id DESC 
STOP WHEN created < now() - INTERVAL '1 hour' 
GROUP BY foreign_key 

즉, 나는 구문을 원하는 나의 테이블의 인덱스 스캔을 실행하고 데이터가 너무 오래되면 중지됩니다 내 쿼리.

+2

필드가'timestamp' 또는'time zone with timestamp'입니까? 제발 스키마를 보여주십시오. –

+0

'auto_incremented_id'가'now() - INTERVAL '1 시간'과 같은 값을 가지고있는 지점을 검색 할 수 있습니다. 그런 다음,'> that_id'에 where 절을 사용하십시오. 그러나 "2 진 검색"은 프로 시저로 수행되어야합니다 (프로시 저 proc 또는 SQL 외부). 또한 id-timestamp 관계가 실제로 있다고 가정하며 이는 진정으로 보장되지 않습니다. –

+0

@CraigRinger 여러 테이블에서 비슷한 쿼리를 실행하고 있습니다. 나는 그들이 모두 정상적인 타임 스탬프라고 확신하지만 나는 월요일에 다시 일할 때까지 확신 할 수 없다. – Jack

답변

1

속도를 높이는 한 가지 방법은 아직 수행하지 않는 경우 table partitioning을 사용하는 것입니다.

CREATE FUNCTION my_fetch() RETURNS SETOF really_big_table AS $$ 
DECLARE 
    -- You could also select only the relevant columns here and change 
    -- the function's return type. 
    curs CURSOR FOR 
     SELECT * FROM really_big_table ORDER BY id DESC; 
BEGIN 
    FOR current_row IN curs LOOP 
     IF current_row.inserted_timestamp > CURRENT_TIMESTAMP - INTERVAL '1 hour' THEN 
      RETURN NEXT current_row; 
     ELSE 
      RETURN; 
     END IF; 
    END LOOP; 
    RETURN; 
END 
$$ STABLE LANGUAGE plpgsql; 

이 그럼 당신은이 작업을 수행 할 수 있습니다 : 당신이 데이터베이스에 수행하려는 경우,

BEGIN; 
DECLARE my_cursor NO SCROLL CURSOR FOR 
    SELECT data, foreign_key, inserted_timestamp 
    FROM really_big_table 
    ORDER BY id DESC; 
FETCH FORWARD 5 FROM my_cursor; 
-- Repeat as many times as you want 
CLOSE my_cursor; 
ROLLBACK; -- Or COMMIT 

그리고 응용 프로그램에서 합계를 계산하거나, 다음은

다른 생각

SELECT SUM(data), foreign_key FROM my_fetch() GROUP BY foreign_key;