열 유형을 CHAR (36)에서 UUID로 변경하는 데 시간을 투자해야합니까?


14

데이터베이스에 이미 몇 백만 개의 행이 있습니다. 스키마를 설계 할 때 PostgreSQL UUID 데이터 형식에 대해 몰랐습니다.

테이블 중 하나에는 16M 개의 행 (샤드 당 약 3.5M-4M 레코드)이 있으며 하루에 약 500K 레코드로 증가합니다. 필요한 경우 몇 시간 동안 프로덕션 시스템을 중단시키는 사치가 여전히 남아 있습니다. 1-2 주 안에이 사치를 누리지 못할 것입니다.

내 질문은 그렇게 할 가치가 있습니까? JOIN 성능, 디스크 공간 사용 (전체 gzip의 덤프는 1.25GiB), 그 특성에 대해 궁금합니다.

테이블 스키마는 다음과 같습니다.

# \d twitter_interactions
                Table "public.twitter_interactions"
         Column          |            Type             | Modifiers 
-------------------------+-----------------------------+-----------
 interaction_id          | character(36)               | not null
 status_text             | character varying(1024)     | not null
 screen_name             | character varying(40)       | not null
 twitter_user_id         | bigint                      | 
 replying_to_screen_name | character varying(40)       | 
 source                  | character varying(240)      | not null
 tweet_id                | bigint                      | not null
 created_at              | timestamp without time zone | not null
Indexes:
    "twitter_interactions_pkey" PRIMARY KEY, btree (interaction_id)
    "twitter_interactions_tweet_id_key" UNIQUE, btree (tweet_id)
    "index_twitter_interactions_on_created_at" btree (created_at)
    "index_twitter_interactions_on_screen_name" btree (screen_name)
Triggers:
    insert_twitter_interactions_trigger BEFORE INSERT ON twitter_interactions FOR EACH ROW EXECUTE PROCEDURE twitter_interactions_insert_trigger()
Number of child tables: 9 (Use \d+ to list them.)

답변:


13

UUID 유형으로 변경하는 것을 고려할 것입니다. char(36)40 바이트 소요uuid 16 하므로 행당 24 바이트를 절약 할 수 있습니다. 1 년에 4GB, 하루에 12MB에 해당합니다. 플러스 인덱스. 가지고있는 하드웨어에 따라 많지는 않지만 그럴 수 있습니다. 이와 같은 개선 기회가 더 있으면 더해집니다.

또한 스키마를 제한하는 제약 조건이 없습니다. interaction_id 에 실제로 올바른 형식인지 확인 . 올바른 유형을 사용하면 그렇게 할 것입니다.

그러나이 방법을 사용 bigint하면 사용하는 것 보다 더 많은 비용을 절약하고 성능을 향상시킬 수 있습니다. 응용 프로그램이 너무 커서 bigintID 열이 작동하지 않을 가능성은 거의 없습니다.


분산 시스템이 있습니다. 여러 데이터 소스가 상호 작용을 위해 ID를 생성하므로 노드 ID에 N 비트를 예약하지 않으면 일반 BIGINT를 사용할 수 없습니다.
— François Beausoleil

3
@ FrançoisBeausoleil, 노드 ID에 대해 N 비트를 예약하는 것은 시퀀스에서 모든 N 번째 숫자를 사용하는 것과 동일하므로 구현하기 쉽습니다. 또한 복합 키 사용을 고려할 수 있습니다.
— Unreason

1
여러 시퀀스 (노드 ID로)를 조정하는 것은 실제로 관리상의 번거 로움으로 사람이 실수하기 쉽습니다. 이 시나리오에서 UUID를 사용하지 않는 이유는 없습니다. 특히 요즘 비트 (메모리 및 스토리지 모두)가 저렴하기 때문입니다. 실제로이 시나리오는 UUID가 수십 년 전에 발명 된 바로 그 이유 입니다. 중앙 집중식 조정없이 분산 시스템간에 데이터를 공유합니다 .
— Basil Bourque

6

나는 상상력의 확장으로 postgres 사람이 아니지만 SQL Server에서 알고있는 것을 기반으로 데이터 페이지에 더 많은 행을 줄수록 더 나은 성능을 얻을 수 있습니다 (디스크에서 데이터를 읽는 것은 일반적으로 가장 비싼 작업). 따라서 36 ish 1 바이트 너비 필드에서 16 바이트 GUID로 전환 하면 비용을 절감 할 수 있습니다. 읽을 수있는 횟수가 적을수록 결과를 더 빨리 반환 할 수 있습니다. 이 모든 것은 물론 GUID / UUID가 테이블의 비즈니스 요구를 충족한다고 가정합니다. UUID가이를 만족하면 bigint ? 그러면 스토리지 비용이 한 줄에 8 바이트 더 줄어 듭니다.

편집 1

들어 문자 데이터 포스트 그레스에서, 그들에 대한 추가 스토리지 비용이 있습니다. 127 바이트 미만의 짧은 문자열에는 1 바이트의 오버 헤드가 있지만 더 이상 4 바이트가 있으면 두 번째 응답자가 36 바이트 필드에 대해 40 바이트의 비용을 발생시키는 방식입니다. 그러나 문자열 압축 옵션도 있으므로 전체 40 비용이 들지 않을 것입니다. 최종 비용이 얼마인지 알 수는 없지만 기본 사항은 남아 있습니다. 16 바이트 이상이면 스토리지 비용이 증가하고 읽는 데 시간이 오래 걸립니다 더 많은 메모리를 소비합니다.

짧은 문자열 (최대 126 바이트)에 대한 스토리지 요구 사항은 1 바이트 + 실제 문자열이며 문자의 경우 공백을 포함합니다. 긴 문자열은 1 대신 4 바이트의 오버 헤드를 갖습니다. 긴 문자열은 시스템에 의해 자동으로 압축되므로 디스크의 물리적 요구 사항은 더 적을 수 있습니다.


3

공간 문제 외에도 올바른 데이터 유형을 사용하려면 모든 테이블을 변경해야합니다. 그렇지 않으면 조인 성능이 나빠질 수 있습니다.


그것은 주어진 것이었지만, 상기시켜 주셔서 감사합니다.
— François Beausoleil

3
이와 같은 주요 변경 사항을 수행 할 때 모든 것을 적어 두는 것이 (어떻게 기억 해야하는지에 관계없이) 일반적으로 돈을 지불한다는 것을 알았습니다.
— mrdenny

3

I / O 절감으로 해석되는 데이터 및 인덱스 (다른 사람들이 말한 것처럼)를 절약하는 것 외에도 고려해야 할 사항은 새로운 가치를 창출하는 방법 interaction_id과 인덱스 및 쿼리 조건 (조인).

인덱스의 경우 크기가 작아 지지만 많은 쿼리에서 인덱스 스캔을 사용하는 경우 UUID로 전환하면 UUID 생성 방법에 따라 인덱스 스캔이 불가능할 bigint수 있으며 훨씬 더 나은 선택 일 수 있습니다.

마지막으로 실제 성능 영향은 사용 패턴 및 데이터 배포 에 따라 달라 지므로 테스트를 실행하고 변경 사항을 테스트 할 수있는 개발 및 테스트 환경이 있어야합니다.

이렇게하면 성능에 미치는 영향에 대해 훨씬 정확한 답변을 얻을 수 있습니다.


사이트 :)에 유용한 기여를 환영에 감사드립니다
— 잭은 말한다 topanswers.xyz 시도

내 액세스 패턴은 날짜 범위, screen_name을 사용하여 가입 또는 UUID를 통해 이루어집니다. 고유 ID에 대한 범위 스캔이 예상되지 않습니다. 유익한 답변을 주셔서 감사합니다.
— François Beausoleil
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.