PostgreSQL의 기본 키인 UUID가 인덱스 성능을 저하합니까?
PostgreSQL 데이터베이스를 사용하여 Rails on Heroku에서 앱을 만들었습니다.
다른 장소에서 데이터를 생성 할 수있는 모바일 장치와 동기화 할 수 있도록 설계된 두 개의 테이블이 있습니다. 따라서 자동 증가 기본 키 외에 GUID를 저장하는 문자열 인 uuid 필드가 있습니다. uuid는 서버와 클라이언트간에 통신되는 것입니다.
서버 측에서 동기화 엔진을 구현 한 후 항상 uuid <-> id간에 매핑해야 할 때 성능 문제가 발생한다는 것을 깨달았습니다 (객체를 작성할 때 저장하기 전에 ID를 가져 오려면 uuid를 쿼리해야하고 데이터를 다시 보낼 때 반대).
이제 UUID를 기본 키로 만 사용하여 쓰기와 읽기를 훨씬 더 간단하고 빠르게 만드는 방법을 생각하고 있습니다.
클러스터 된 기본 키 인덱스를 사용할 때 기본 키로 UUID가 때때로 나쁜 인덱스 성능 (인덱스 조각화)을 제공 할 수 있다는 것을 읽었습니다. PostgreSQL이이 문제를 겪고 있습니까? 아니면 UUID를 기본 키로 사용해도 괜찮습니까?
오늘 이미 UUID 열이 있으므로 일반 ID 열을 삭제했기 때문에 스토리지 현명한 것이 더 나을 것입니다.
(나는 Heroku Postgres에서 일합니다)
우리는 UUID를 일부 시스템에서 기본 키로 사용하며 훌륭하게 작동합니다.
uuid-ossp확장 기능 을 사용하는 것이 좋으며 postgres가 UUID를 생성하도록하십시오.
heroku pg:psql
psql (9.1.4, server 9.1.6)
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.
dcvgo3fvfmbl44=> CREATE EXTENSION "uuid-ossp";
CREATE EXTENSION
dcvgo3fvfmbl44=> CREATE TABLE test (id uuid primary key default uuid_generate_v4(), name text);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_pkey" for table "test"
CREATE TABLE
dcvgo3fvfmbl44=> \d test
Table "public.test"
Column | Type | Modifiers
--------+------+-------------------------------------
id | uuid | not null default uuid_generate_v4() name | text |
Indexes:
"test_pkey" PRIMARY KEY, btree (id)
dcvgo3fvfmbl44=> insert into test (name) values ('hgmnz');
INSERT 0 1
dcvgo3fvfmbl44=> select * from test;
id | name
--------------------------------------+-------
e535d271-91be-4291-832f-f7883a2d374f | hgmnz
(1 row)
성능 영향 편집
그것은 것입니다 항상 작업 부하에 따라 달라집니다.
정수 기본 키는 유사 데이터가 더 가깝게 위치하는 지역성의 이점이 있습니다. 이것은 예를 들어 도움이 될 수 있습니다 : WHERE id between 1 and 10000비록 잠금 경합이 더 나쁘더라도 범위 유형 쿼리 .
항상 기본 키 조회를 수행한다는 점에서 읽기 워크로드가 완전히 임의적이라면 측정 가능한 성능 저하가 없어야합니다. 더 큰 데이터 유형에 대해서만 비용을 지불하면됩니다.
이 테이블에 많이 쓰시나요?이 테이블이 매우 큽니까? 내가 이것을 측정하지는 않았지만 그 인덱스를 유지하는 데 영향을 미칠 수 있습니다. 많은 데이터 세트의 경우 UUID는 괜찮으며 UUID를 식별자로 사용하면 몇 가지 멋진 속성이 있습니다.
마지막으로, 문제가 된 UUID PK로 충분히 큰 테이블을 실행 한 적이 없기 때문에 이에 대해 논의하거나 조언 할 수있는 가장 자격이있는 사람이 아닐 수 있습니다. YMMV. (그렇게 말하면서 접근 방식에 문제가있는 사람들의 이야기를 듣고 싶습니다!)
수락 된 답변에 나와 있듯이이 경우 범위 쿼리가 느릴 수 있지만 id.
자동 증가는 자연적으로 날짜별로 정렬되므로 자동 증가를 사용하면 데이터가 디스크에 시간순으로 저장되어 (B- 트리 참조) 읽기 속도가 빨라집니다 (HDD 검색 없음). 예를 들어 모든 사용자를 나열하는 경우 자연 순서는 자동 증가와 동일한 생성 날짜별로 이루어 지므로 범위 쿼리는 SSD에서 HDD에서 더 빠르게 실행됩니다. SSD는 항상 무작위로 설계 되었기 때문에 차이가 존재하지 않을 것입니다. 액세스 (헤드 검색 없음, 관련된 기계 부품 없음, 순수한 전기)
'Program Club' 카테고리의 다른 글
| UIView 용 iOS viewDidLoad (0) | 2020.12.27 |
|---|---|
| 공용체를 통한 유형 실행은 C99에서 지정되지 않았으며 C11에서 지정 되었습니까? (0) | 2020.12.27 |
| JDK8 및 JDK10에서 삼항 연산자의 동작 차이 (0) | 2020.12.27 |
| Team Foundation Server 2010에 솔루션을 추가 할 때 표시되는 경고 (0) | 2020.12.27 |
| C # 5 Async / Await-* 동시 *입니까? (0) | 2020.12.27 |