2011-11-30 4 views
5

PostgreSQL 9.0의 DELETE/INSERT 시퀀스에 처리량 문제가 있습니다. 나는 상황을 개선하기위한 아이디어를 찾고있다.PostgreSQL DELETE/INSERT 처리량 문제

우리가 사용할 수있는 하드웨어에서, 보통 테스트 할 각 테이블의 1m 행을 훨씬 넘어서는 새 행을 3000/s의 속도로 계속 삽입 할 수 있습니다. 그러나 행을 삭제하고 다른 데이터로 다시 삽입하는 모드로 전환하면 성능이 250 행/초 (10 개의 테이블에 걸쳐 균등하게)의 크기보다 크게 감소합니다.

테이블에 제약 조건이 없습니다. shared_buffers (2GB) 내에있는 1GB의 총 색인 크기 (테이블 당 1m 행)가있는 각 테이블에는 2 개의 색인 된 열이 있습니다. 총 데이터 크기 (테이블 당 1m 행)는 총 시스템 RAM보다 훨씬 적은 12GB입니다. 이것은 비상시에 재 구축 할 수있는 섀도우 데이터베이스이므로 fsync를 해제하여 실행합니다.

우리가 채우기 모드에있을 때, 우리는 데이터가 추가되고 있기 때문에 탐색 시간이 매우 낮은 디스크에서 혜택을 누릴 것으로 생각된다

. 그러나 업데이트 모드로 전환하면 많은 일이 발생합니다 (이전 행을 삭제할 가능성이 있음). 랜덤 디스크는 ~ 8ms의 비용을 요구합니다 (= 초당 ~ 125). 하드웨어 변경없이 UPDATE/re-INSERT 작업의 성능을 크게 향상시킬 수 있습니까?

EDIT1 : 두 가지 사양 하드웨어 플랫폼에서 perf 테스트를 수행하고 있습니다. 이전에 인용 한 수치는 고급 사양 플랫폼에서 나온 수치입니다. 방금 저사양 플랫폼에서 테스트를 마쳤습니다. 이 테스트에서는 가능한 한 빨리 새 행을 삽입하고 1 초당 1 행을 삽입 할 때까지 10 초마다 삽입 률을 기록합니다. 이 시점에서 필자의 테스트 스크립트는 임의의 행을 업데이트하는 것으로 전환됩니다.

Perf results graph

이 그래프 측정 갱신 레이트가 모두 10 ~ 표/초 인구 중 상기 갱신 율이 모두 10 개 초 테이블/행 < 10 업데이트되었던 업데이트 150이었다 나타낸다.

@wildplasser은 - 기계는 실제 기계가 아니라 VM입니다. 10 개의 테이블에는 모두 다음과 같은 스키마가 있습니다. 은 "업데이트"수행되는

CREATE TABLE objecti_servicea_item1 
(
    iss_scs_id text, 
    iss_generation bigint, 
    boolattr1 boolean, 
    boolattr2 boolean, 
    boolattr3 boolean, 
    boolattr4 boolean, 
    boolattr5 boolean, 
    boolattr6 boolean, 
    boolattr7 boolean, 
    boolattr8 boolean, 
    boolattr9 boolean, 
    boolattr10 boolean, 
    boolattr11 boolean, 
    boolattr12 boolean, 
    boolattr13 boolean, 
    boolattr14 boolean, 
    boolattr15 boolean, 
    boolattr16 boolean, 
    boolattr17 boolean, 
    intattr1 bigint, 
    intattr2 bigint, 
    intattr3 bigint, 
    intattr4 bigint, 
    intattr5 bigint, 
    intattr6 bigint, 
    intattr7 bigint, 
    intattr8 bigint, 
    intattr9 bigint, 
    intattr10 bigint, 
    intattr11 bigint, 
    intattr12 bigint, 
    intattr13 bigint, 
    intattr14 bigint, 
    intattr15 bigint, 
    intattr16 bigint, 
    intattr17 bigint, 
    strattr1 text[], 
    strattr2 text[], 
    strattr3 text[], 
    strattr4 text[], 
    strattr5 text[], 
    strattr6 text[], 
    strattr7 text[], 
    strattr8 text[], 
    strattr9 text[], 
    strattr10 text[], 
    strattr11 text[], 
    strattr12 text[], 
    strattr13 text[], 
    strattr14 text[], 
    strattr15 text[], 
    strattr16 text[], 
    strattr17 text[] 
) 
WITH (
    OIDS=FALSE 
); 
CREATE INDEX objecti_servicea_item1_idx_iss_generation 
    ON objecti_servicea_item1 
    USING btree 
    (iss_generation); 
CREATE INDEX objecti_servicea_item1_idx_iss_scs_id 
    ON objecti_servicea_item1 
    USING btree 
    (iss_scs_id); 

은 10 개 각 테이블에 대해 다음 SQL을 포함한다.

DELETE FROM ObjectI_ServiceA_Item1 WHERE iss_scs_id = 'ObjUID39' 
INSERT INTO ObjectI_ServiceA_Item1 
VALUES ('ObjUID39', '2', '0', NULL, '0' 
, NULL, NULL, NULL, '1', '1', NULL, '0' 
, NULL, NULL, NULL, NULL, '0', '1', '1' 
, '-70131725335162304', NULL, NULL, '-5241412302283462832' 
, NULL, '310555201689715409', '575266664603129486' 
, NULL, NULL, NULL, NULL, NULL, NULL 
, '-8898556182251816700', NULL, '3325820251460628173' 
, '-3434461681822953613' 
, NULL 
, E'{pvmo2mt7dma37roqpuqjeu4p8b,"uo1kjt1b3eu9g5vlf0d02l6iaq\\\\\\",",45kfns1j80gc7fri0dm29hnrjo}' 
, NULL, NULL 
, E'{omjv460do8cb7abn8t3eg5b6ki,"a7hrlninbk1rmu6h3rd4787l7f\\\\\\",",24n3ipfua5spma2vrj2aji98g3}' 
, NULL 
, E'{1821v2n2ermm4jujrucu5tekmm,"ukgst224964uhthkhjj9v189ft\\\\\\",",6dfsaniq9mftvbdr8g1sr8e6as}' 
, E'{c2a9gvf0fnd38m8vprlhkp2n74,"ts86vbat12lfr0d7l4tc29k9uk\\\\\\",",32b5j9r5evmrie4h21hi10dpot}' 
, E'{18pve4cmcbrjiom9bpvoo1l4n0,"hrqcsane6r0n7u2oj79bj605rh\\\\\\",",32q5n18q3qbkuit605fv47270o}' 
, E'{l3bf96shrpnnqgt35m7574t5n4,"cpol4k8296hbdqc9kac79oj0ua\\\\\\",",eqioulmb7vav10lbnc5jg752df}' 
, E'{5fai108h163hpjcv0ofgfi7c28,"ci958009ddak3li7bp37slcs8i\\\\\\",",2itstj01tkprlul8f530uhs6s2}' 
, E'{ueqfkdold8vc84jllr4b2cakt5,"t5vbea4r7tva091pa8j6886t60\\\\\\",",ul82aovhil1lpd290s14vd0p3i}' 
, NULL, NULL, NULL, NULL, NULL) 

내 perf 테스트의 첫 번째 단계에서 DELETE 명령은 항상 아무 것도 수행하지 않습니다.

@Frank Heikens는 - 내가 업데이트를 실행하고있는 반환 한 테스트에서 10 개 스레드에서 수행되고있다. 그러나 업데이트는 동일한 행에 대한 여러 업데이트가 항상 동일한 스레드에서 처리되도록하는 방식으로 스레드에 할당됩니다.

+0

VM 또는 실제 기계입니까? 또한 테이블 정의 && 쿼리 및 결과 쿼리 계획 (의 단편)을 질문에 추가하십시오. – wildplasser

+0

자물쇠가 있는지 확인 했습니까? 여러 프로세스가 동일한 레코드를 삭제하려고 할 수 있습니다. –

+0

귀하의 의견에 회신하기 위해 내 게시물을 편집했습니다. – mchr

답변

3

이 데이터 모델은 아름다움이 아닙니다. DELETE - INSERT 중 하나입니다. UPDATE의 문제점은 무엇입니까? iss_generation 및 iss_scs_id가 UPDATE에서 변경되지 않으면 데이터베이스에서 HOT update (힙 오버플로 튜플)을 수행하여 성능을 향상시킬 수 있습니다. UPDATE는 또한 fillfactor가 낮을수록 혜택을 볼 수 있습니다. 당신이 기록의 DELETE 작업을 수행 할 때

, 그 기록은 INSERT가 갈 곳과는 다른 블록에있을 수 있습니다. 낮은 fillfactor를 사용하고 UPDATE를 사용하면 데이터베이스에 디스크의 동일한 블록에있는 업데이트 된 레코드를 삭제하고 INSERT하는 옵션을 제공 할 수 있습니다. 이렇게하면 임의의 I/O가 덜 발생하게됩니다.HOT를 사용할 수있는 경우 인덱스를 업데이트 할 필요가 없으므로 상황이 더욱 좋아집니다.

1

잘 모르겠지만 fillfactor를 변경하면 도움이 될까요?

+0

제안 해 주셔서 감사합니다. – mchr

0

메모리의 csv에서 삭제/복사를 성공했습니다.