2011-02-02 2 views
4

내 질문은 포스트 그레스의 작동 방식의 내장에 관한 것이다 other_table_id1, 주 및 other_table_id2에 추가 인덱스와Postgres : 여러 개의 열이있는 테이블 또는 더 적은 수의 열이있는 여러 개의 테이블?


CREATE TABLE A (
    id SERIAL, 
    name VARCHAR(32), 
    type VARCHAR(32) NOT NULL, 
    priority SMALLINT NOT NULL, 
    x SMALLINT NOT NULL, 
    y SMALLINT NOT NULL, 
    start timestamp with time zone, 
    end timestamp with time zone, 
    state Astate NOT NULL, 
    other_table_id1 bigint REFERENCES W, 
    other_table_id2 bigint NOT NULL REFERENCES S, 
    PRIMARY KEY(id) 
);

:

나는 테이블을 가지고있다.

테이블이 상당히 크고 열에 대한 업데이트가 많이 있습니다 : other_table_id1, state. 시작 및 끝 열에 대한 몇 가지 업데이트가 있지만 나머지는 변경되지 않습니다. (Astate는 열 상태에 대한 열거 형입니다.)

가장 자주 업데이트되는 두 개의 열을 별도의 테이블로 분리하는 것이 적합한 지 궁금합니다. 내가 얻고 자하는 것은 성능에 관한 것인데, 그 정보를 찾거나 업데이트의 무게를 줄이려면 (아마도?) 더 짧은 행을 읽고 쓰는 데 드는 비용이 적기 때문입니다. 그러나 특정 항목의 모든 데이터를 한꺼번에 가져올 때 (때때로) 조인 비용과 비교할 필요가 있습니다.

한순간에 나는 각 열이 별도로 저장된다는 인상하에있었습니다. 하지만 나중에 다른 열을 사용하여 데이터를 조회 할 때 테이블의 한쪽에있는 열의 너비를 줄이면 성능이 영향을받습니다 (행이 함께 저장되므로 전체 행 길이가 더 짧아 라.) 그래서 나는 행에 대한 모든 데이터가 물리적으로 디스크에 함께 저장된다는 인상을 받고 있습니다. 그래서 제안 된 테이블 분할은 도움이 될 것입니다. 현재 상태를 업데이트하는 데 4 바이트를 쓸 때 실제로 변경하지 않는 텍스트 (이름, 유형)의 64 바이트를 다시 작성한다고 생각합니까?

저는 테이블 "정규화"에 익숙하지 않고 Postgres의 내부에 익숙하지 않으므로 먼저 작업을 수행하지 않고도 트레이드 오프를 예측하기위한 조언과 권장 사례를 찾고 있습니다. 그 일은 가치가있었습니다. 변경 작업을 수행하려면 이미 최적화 된 쿼리를 다시 작성해야하기 때문에 기대할 수있는 결과를 잘 이해하고 있어야합니다. 고마워, M.

답변

4

큰 행을 업데이트하려면 비용이 있습니다.

수식이 도움이 될 수 있습니다.당신이 분할하지 않는 경우, 비용은

비용 = 쑤 + YS

:

U는 전체 행의 갱신 (테이블이 분할되지 않음)의

S = 비용 = 당신이 그것을 분할하는 경우

X를 선택, Y =

그런 행동의 수, 당신은이를 이해하려고 노력하고 있습니다 :

비용 = GU1 + HU2 + XS1 + YS2

여기서 작은 테이블 (저비용) 큰 테이블 (저비용)

S1의

U2 = 업데이트

U1 = 업데이트 = 큰 테이블

S2 = 선택 작은 테이블에서 선택

g은 H는 X는 Y가 = 빈도에 개별 행동이 발생합니다

따라서 g >> h 인 경우이를 해제해야합니다. 특히 x >> y이면 정말로 지불합니다.

EDIT : 의견에 따라 데이터베이스가 지속적으로로드되고 비활성 상태가 아닌 경우 이러한 비용이 훨씬 더 중요하게됩니다. 대신에 서버가 지속적인 부하를 경험하지 않으면 초당 1 또는 2 trx로 거의 비활성 상태가되고 긴 비활성 상태 ("긴"= 몇 초간)가 있으면 아무 것도 작동하지 않습니다. 성능 혜택이 실제 측정 가능한 것으로 나타나지 않기 때문에 코드를 작성하십시오.

+0

감사합니다 켄, 이것은 내가 가려고하는 방향입니다. U1과 U2 (와 U)가 모두 열 너비에 비례한다고 가정 해주십시오. 오버 헤드 (U1 + U2 <1.2 * U)의 여백 내에서 (U1 + U2) == U라고 말하겠습니까? –

+0

그리고 두 테이블의 행 사이에 1 : 1 관계가 있으므로 조인 비용 (U1 + U2)을 말할 수 있습니까? –

+0

정정 : 가입 (S1 + S2) 비용이 부과 될지도 모른다고 생각합니다 ... –

0

열을 저장하는 방법에 상관없이 가치가 분열 될만한 가치가 있습니다. 동시성 문제를 줄이고 부분 데이터 조회 속도를 높이고 보조 키를 만들지 않고도 검색 할 수 있도록 세 개의 인덱스를 제공하여 인덱스 검색 속도를 높일 수 있습니다.

내부 결합의 영향을 줄이거 나 한 번에 너무 많은 행만 허용하여 줄이거 나 줄일 수 있습니다. 직접 조회를 허용하지 않고 표시되는 행에 내부 결합 데이터 만 표시하거나 (한 번에 화면에 너무 많은 행만 표시 할 수 있음) 또는 현재 선택된 행에 대한 추가 데이터를 표시하여 인터페이스를 제공하거나 찾아보기 단추로 조회마다 X 행만 허용하십시오. 치트를 사용하는 경우 확장 검색 결과를 캐시해야합니다.

+0

감사합니다. 인간이 이러한 테이블을 거의 정렬하지 않기 때문에 "부정 행위"에 대한 제안은 내 응용 프로그램과 실제로 관련이 없습니다. 그것은 모두 기계를위한 것이므로, 열이 실제로 보일 필요가없는 한 이미 열을 찾지 않습니다. (즉, SELECT id, state, other_table_id2 WHEN ...) 조인 비용 증가 또는 감소 된 테이블 크기의 절감을 예측할 수있는 방법이 있습니까? –

+0

데이터베이스 관리를 살펴보십시오.이 모든 것을 결정하기 위해 많은 분석이 필요하기 때문에 전체 경력 분야입니다. 솔루션의 기회 비용을 예측할뿐만 아니라 모든 솔루션을 고려해야합니다. 데이터가 업데이트되는 시점을 예측해야하며 테이블을 분할하면 충돌을 줄일 수 있습니다. 가장 효율적인 솔루션을 찾으려면 모든 가능한 조합에 대해 이것을 계산해야합니다. 그러나 INNER JOIN이 가끔씩 만 존재하고 테이블의 일부분을 독립적으로 업데이트 할 수있는 많은 양의 데이터로 작업 할 때 분할하는 것이 항상 유용합니다. –

2

PostgreSQL의 구현 세부 사항 중 하나는 디스크에 저장된 행을 "업데이트"하지 않으며 항상 새로운 버전을 작성한다는 것입니다. 따라서 Oracle과 같이 처음부터 고정 폭 열을 함께 사용하면 빠른 승리는 없습니다 (예 : iirc).

함께 업데이트되는 경향이 있는지 여부에 따라 서로 다른 테이블에 열을 그룹화하면 청소해야 할 쓰레기가 줄어들 수 있습니다. 결과를 실험하고 측정하는 것이 중요합니다. 자주 업데이트되는 일부 데이터가있는 경우 테이블의 "fillfactor"설정을 조사해야합니다. 이 설정은 PostgreSQL을 삽입 할 때 테이블 페이지에 여유 공간을 남기므로 가능한 경우 이전 버전과 동일한 페이지에 행의 업데이트 된 버전을 추가 할 수 있습니다. 이렇게하면 인덱스가 가리키는 인덱스를 의미 할 수 있으므로 업데이트의 부담을 줄일 수 있습니다. 행을 업데이트하지 않아도되므로 테이블이 디스크 전체에 더 많은 공간을 차지하게됩니다.

Xaade에서 언급했듯이이 주제에 관해 많은 자료가 있습니다. 나는 변화의 영향을 측정 할 필요가 있다는 것에 대한 제 의견을 강조하고 싶습니다. 때로는 커다란 승리처럼 보일 수있는 것이 실제로는 아닐 수도 있습니다.

관련 문제