2013-04-08 3 views
1

나는 데이터베이스를 사용하여 파일 목록과 각각의 메타 데이터와 관련된 메타 데이터를 나타냅니다. 이 파일 목록을 정기적으로 업데이트하고, 새 파일 만 추가하고 더 이상 존재하지 않는 파일을 삭제해야합니다 (메타 데이터가 손실 될 수 있으므로 테이블의 기존 행을 건드리지 않아야 함).postgresql에서 효율적인 인서트 삽입

내 현재 쿼리는 약 10000 개의 파일이있을 때 단 몇 초만 걸리지 만 현재 150000- 파일 테이블에서는 1 시간이 걸립니다.

  1. 하면 스캔
  2. DELETE FROM files WHERE path NOT IN (SELECT path FROM newfiles);
  3. INSERT INTO files (SELECT * FROM newfiles WHERE path NOT IN (SELECT path FROM files));

의 결과 테이블 "newfiles"을 채우기 : 인터넷에서 몇 가지 조사 후

, 나는 다음과 같은 과정이었다 색인도 있습니다 :

CREATE INDEX "files_path" ON "files" ("path"); 
CREATE INDEX "files_path_like" ON "files" ("path" varchar_pattern_ops); 
CREATE INDEX "files_path" ON "newfiles" ("path"); 
CREATE INDEX "files_path_like" ON "newfiles" ("path" varchar_pattern_ops); 

(주로 데이터베이스에서 이러한 색인을 사용합니다. 내 응용 프로그램에 파일로 검색 엔진이 있습니다.)

150000 개의 파일이있을 때 이러한 두 쿼리는 각각 1 시간 이상 걸립니다. 어떻게 최적화 할 수 있습니까?

감사합니다.

+0

가끔 실행 가능한 옵션은 새로운 파티션을 추가하는 것입니다 : 부모 테이블에 'INHERITS'라는 새로운 테이블을 만들고, 적절한 제약 조건을 추가하고, 채우고, 인덱스를 생성하십시오. 이는 새로운 데이터를 단일 제약 조건으로 명확하게 분할 할 수있는 경우에만 작동합니다. –

+0

이것은 메모리 또는 디스크 IO 문제와 비슷하게 들립니다. 150K 행은 엄청난 양이 아닙니다. 아마도 포스트 그레스에 더 많은 메모리를 할당해야할까요? 그때조차도 테이블이 얼마나 큽니다. 디스크에서이 모든 데이터를 읽는 데 1 시간이 걸리지 않아야합니다. – AngerClown

답변

1

이 같이 대신 NOT INNOT EXISTS을 시도해보십시오 newfiles 처음부터 때마다 채워집니다 경우

는 또한
DELETE FROM files WHERE NOT EXISTS 
    (SELECT 1 FROM newfiles WHERE newfiles.path=files.path); 

, 확인 당신 ANALYZE newfiles 최적화 프로그램이 작동 할 수 있도록, 그것을 사용하는 모든 쿼리를 발행하기 전에 좋은 통계.

그래도 해결되지 않으면 질문에 EXPLAIN 또는 EXPLAIN ANALYZE을 입력하여 실행 계획을 세우고 질문에 추가하십시오.

+0

여기에 관해서 내가 묻는 것을 잊어 버려서 죄송합니다 ... -_- – alphatiger

+0

그 덕분에 실제로는 각 쿼리에 대해 1 초도 채 걸리지 않았습니다. 두 옵션을 모두 시도한 후에는 도움이되는 NOT IN 대신 NOT EXISTS를 사용합니다. 대단히 감사합니다! – alphatiger