2010-06-23 8 views
8

3 열 인덱스와 배열 열이있는 매우 큰 테이블 (20M 레코드)이 있습니다. 배열 열은 모든 행에 대해 매일 새 값을 추가하여 업데이트됩니다. 또한 삽입이 있지만 업데이트만큼이나 많지는 않습니다.배열이 많고 업데이트가 많은 대형 테이블에서 PostgreSQL 속도가 느림

배열의 데이터는 [[date_id_1, my_value_for_date_1], [date_id_2, my_value_for_date_2]]과 같은 세 가지 키에 해당하는 일일 측정을 나타냅니다. 이러한 일별 값의 그래프를 그리는 데 사용됩니다. 시간이 지남에 따라 키 값 (a, b, c)을 시각화하려고한다고 가정하면 SELECT values FROM t WHERE a = my_a AND b = my_b AND c = my_c입니다. 그런 다음 values 배열을 사용하여 그래프를 그립니다.

일일 1 회 대량으로 발생하는 업데이트의 성능이 시간이지나면서 크게 악화되었습니다.

PostgreSQL 8.3.8 사용.

해결 방법을 찾을 수있는 힌트를 줄 수 있습니까? Postgres의 일부 매개 변수를 조정하여 다른 데이터베이스로 이동하는 것 (비 관계형 데이터베이스가이 특정 테이블에 더 적합 할 것으로 추측되지만 그와 관련된 많은 경험이 없습니다) 일 수도 있습니다.

+1

http://archives.postgresql.org/pgsql-performance/ –

+1

@Milen 힌트를 보내 주셔서 감사합니다. 필자는 StackOverflow에 대한 열렬한 팬이며, 특화된 메일 링리스트 나 포럼보다 선호합니다.나는 그 사람들이 여전히 그들의 자리를 가지고 있다는 데 동의하지만, 나는 그곳에 대한 도움을 찾을 수 없다면 분명히 거기에 갈 것이다. – ibz

+0

https://stackoverflow.com/questions/3361291/slow-simple-update-query-on-postgresql-database-with-3-million-rows – rogerdpack

답변

16

필자는 테이블에 FILLFACTOR를 살펴볼 것입니다. 기본적으로 100으로 설정되었으므로 70으로 낮출 수 있습니다 (처음부터). 그런 다음 테이블을 다시 작성하려면 VACUUM FULL을 수행해야합니다.

ALTER TABLE tablename SET (FILLFACTOR = 70); 
VACUUM FULL tablename; 
REINDEX TABLE tablename; 

이 UPDATE에게 다른 페이지에 배치하는 것이 더 효율적입니다 원래, 같은 페이지에 행의 업데이트 된 사본을 배치 할 수있는 기회를 제공합니다. 또는 데이터베이스가 이전에 업데이트 된 많은 부분에서 이미 조각난 경우 이미 충분할 수도 있습니다. 이제 데이터베이스에는 HOT updates을 수행 할 수있는 옵션이 있습니다. 업데이트 할 열이 임의의 인덱스와 관련이 없다고 가정합니다.

+0

내가보기에 HOT는 UPDATE를 수행 할 때 인덱스를 업데이트하지 않는 방법입니다. 권리? 그렇다면 시간이 지남에 따라 성능이 왜 떨어질까요? 4 개월 전과 마찬가지로 인덱스가 업데이트되었지만 그 이후로는 성능이 크게 저하되었습니다. – ibz

+3

새 버전의 레코드 (업데이트로 인해)가 다른 페이지에 저장되므로 성능이 저하 될 수 있습니다. 많은 기록이 있으면 많은 페이지를 보유하게됩니다. 새 버전을 원본 버전에서 멀리 배치하면 쿼리 계획에 영향을 미칩니다. EXPLAIN을 사용하면 어떤 일이 발생하는지 볼 수 있습니다. 또한 CLUSTER는 인덱스가 정보를 저장하는 순서대로 레코드를 저장하는 것으로 간주합니다. fillfactor로 재생해야하며, 업데이트 된 레코드는 원본 레코드와 가깝도록해야합니다. –

+0

알겠습니다. 그래서 내가 질의를 할 때마다, 내가 원하는 것에 도달하기 전에 죽은 행을 통과해야만합니까? 이것이 당신이 의미하는 (과도하게 단순화 된) 것입니까? 즉, fillfactor가 실제로 도움이되어야 함을 의미합니다. HOT 업데이트가 fillfactor와 관련이 있습니까? fillfactor를 변경 한 후 HOT 업데이트를 활성화하려면 어떻게합니까? – ibz

2

배열이 여기로가는 길인지 확실하지 않습니다.

별도의 테이블에 하나의 값과 행당 키를 저장하지 마십시오. 일괄 업데이트는 순수 삽입 작업입니다.

1

글쎄 3 열 인덱스는 걱정할 필요가 없습니다. 그렇다고 반드시 그렇게 느리게 만들지는 않습니다. 그러나 그 배열 열은 참으로 문제 일 수 있습니다. 매일 그 배열 열에 값을 추가한다고합니다. 추가로, 당신은 모든 20 mln에 값을 추가하는 것을 의미합니까? 테이블에 기록? 아니면 그냥 몇 가지 기록?

상황이 완전히 나에게 명확하지는 않지만 해당 배열 열을 제거하는 방법을 살펴볼 것을 제안합니다. 예를 들어 별도의 테이블로 만듭니다. 그러나 이는 상황에 따라 달라지며 옵션이 아닐 수도 있습니다. 그것은 나일지도 모르지만, 나는 항상 내 테이블 중 하나에 그런 칼럼을 가지고 '더러운'느낌. 대부분의 경우 해당 배열 열로 해결하려는 문제에 대한 더 나은 솔루션이 있습니다. 즉, 그러한 열이 유효한 상황은 분명하지만, 지금은 아무 것도 생각할 수 없습니다. 20 만 달러짜리 테이블에는 없다. 레코드 수.

+2

일부 배열에 요소를 추가하는 것이지 모두를 추가하는 것이 아닙니다. 20 mln. 나는 다른 테이블을 사용 했었지만, 그것은 거대하게 만들고 성능은 훨씬 나빠졌습니다. 이러한 배열에 데이터를 비정규 화하고 저장하기로 결정하여 선택을 크게 개선하고 처음에는 업데이트를 악화시키지 않았습니다 (시간이 지남에 따라 악화되는 것 같음). – ibz

+0

표 및 배열에있는 데이터의 본질과 그 관계에 대해 더 자세히 설명해 주시겠습니까? 여전히 더 나은 해결책이있을 수 있습니다. :) – pyrocumulus

+0

자세한 내용을 추가했습니다. 두 번째 단락을 참조하십시오. 그것은 정말로 중요하다고 확신하지 않습니다. – ibz

2

문제는 업데이트 중입니다. 스키마를 배열 기반에서 하루에 여러 행으로 변경하면 성능 문제가 해결됩니다.

어떤 종류의 cronjob과 함께 나중에 배열에 롤업을 추가 할 수는 있지만 업데이트는하지 마십시오.

+0

"처음부터 배열을 빌드해야한다면 (배열을 롤업하는 것"은 정말로 느릴 것입니다. (각 a, b, c의 조합마다). – ibz

관련 문제