범용 고유 식별자(UUID)는 레코드를 식별하는 데 사용되는 16바이트 값입니다. UUID에 대한 자세한 내용은 Wikipedia를 참조하십시오.UUIDv4, UUIDv7 등 다양한 UUID 변형이 존재하지만(RFC 9562 참조), ClickHouse는 삽입된 UUID가 특정 변형을 준수하는지 검증하지 않습니다.
UUID는 내부적으로 16개의 임의 바이트로 이루어진 시퀀스로 처리되며, SQL 수준에서는 8-4-4-4-12 표현을 사용합니다.예시 UUID 값:
61f0c404-5cb3-11e7-907b-a6006ad3dba0
기본 UUID는 모든 자리가 0입니다. 예를 들어 새 레코드가 삽입되었지만 UUID 컬럼 값이 지정되지 않은 경우에 사용됩니다:
00000000-0000-0000-0000-000000000000
역사적인 이유로 UUID는 뒤 절반을 기준으로 정렬됩니다.이는 UUIDv4 값에는 문제가 없지만, 프라이머리 인덱스 정의에 사용되는 UUIDv7 컬럼에서는 성능이 저하될 수 있습니다(순서 지정 키 또는 파티션 키에 사용하는 경우는 괜찮습니다).
좀 더 구체적으로 말하면, UUIDv7 값은 앞 절반에 타임스탬프가 있고 뒤 절반에 counter가 있습니다.
따라서 희소 프라이머리 인덱스의 UUIDv7 정렬(즉, 각 인덱스 granule의 첫 번째 값)은 counter 필드를 기준으로 이루어집니다.
UUID가 앞 절반(타임스탬프)을 기준으로 정렬된다고 가정하면, 쿼리 시작 시 수행되는 프라이머리 키 인덱스 분석 단계에서 하나의 파트를 제외한 모든 파트의 모든 마크를 가지치기할 수 있을 것으로 예상됩니다.
그러나 뒤 절반(counter)을 기준으로 정렬하면 모든 파트에서 적어도 하나의 마크가 반환될 것으로 예상되며, 이로 인해 불필요한 디스크 접근이 발생합니다.
예시:
Query
CREATE TABLE tab (uuid UUID) ENGINE = MergeTree PRIMARY KEY (uuid);INSERT INTO tab SELECT generateUUIDv7() FROM numbers(2);INSERT INTO tab SELECT generateUUIDv7() FROM numbers(2);INSERT INTO tab SELECT generateUUIDv7() FROM numbers(2);INSERT INTO tab SELECT generateUUIDv7() FROM numbers(2);INSERT INTO tab SELECT generateUUIDv7() FROM numbers(2);SELECT * FROM tab;
CREATE TABLE tab (uuid UUID) ENGINE = MergeTree PRIMARY KEY (UUIDv7ToDateTime(uuid));-- Or alternatively: [...] PRIMARY KEY (toStartOfHour(UUIDv7ToDateTime(uuid)));INSERT INTO tab SELECT generateUUIDv7() FROM numbers(2);INSERT INTO tab SELECT generateUUIDv7() FROM numbers(2);INSERT INTO tab SELECT generateUUIDv7() FROM numbers(2);INSERT INTO tab SELECT generateUUIDv7() FROM numbers(2);INSERT INTO tab SELECT generateUUIDv7() FROM numbers(2);SELECT * FROM tab;