Jaki jest najbardziej wydajny typ kolumny UUID

15

Do przechowywania 128-bitowego identyfikatora UUID istnieje wiele opcji przechowywania:

  1. kolumna bajtowa [16]
  2. dwie kolumny bigint / long (64 bity)
  3. kolumna CHAR (36) - 32 cyfry szesnastkowe + 4 myślniki.
  4. kolumna specyficzna dla bazy danych UUID, jeśli db ją obsługuje

Które z nich są najbardziej wydajne z punktu widzenia indeksowania? Jeśli db nie obsługuje dedykowanego typu UUID, które z 1, 2, 3 są najlepszymi kandydatami?

Vlad Mihalcea
źródło
1
Jest to nieco zbyt „zależy” - wiele szczegółów implementacyjnych.
Craig Ringer
2
Nigdy nie wybrałbym 3: nigdy nie przechowuję czegoś w 36 bajtach, gdy można to zrobić w 16. Używam raw(16)w Oracle i uuidPostgreSQL.
Colin 't Hart
1
im prościej, tym lepiej.
akuzminsky
uuid>> bytea>> textz CHECKograniczeniem> varchar(36)>> char(36). Zobacz: dba.stackexchange.com/a/89433/3684 i dba.stackexchange.com/a/115316/3684 .
Erwin Brandstetter,

Odpowiedzi:

15

Dedykowany uuidtyp jest najlepszym wyborem dla PostgreSQL. Trudno powiedzieć z innymi bazami danych - nie jest niemożliwe, aby ktoś wszczepił auuid typ, który jest przechowywany mniej wydajnie niż zwykły typ bajtu.

Ponownie w PostgreSQL byteabyłby rozsądny sposób przechowywania UUID, gdybyś nie miał tego uuidtypu. W przypadku innych baz danych zależy to od sposobu przechowywania danych binarnych.

Tam, gdzie to możliwe, zdecydowanie unikałbym używania heksów z myślnikami. Porównywanie, sortowanie i przechowywanie jest znacznie mniej wydajne.

Tak naprawdę „nie (2) lub (3)”. Zawsze. Użyj (4) tam, gdzie jest to obsługiwane, (1) w przeciwnym razie.

Craig Ringer
źródło
Należy zauważyć, że typ UUID PostgreSQL nie jest obsługiwany natywnie w tablicach, czy też został naprawiony? postgresql.org/message-id/…
Christophe Roussy
@ChristopheRoussy To z 2013 roku. To był drobny niedopatrzenie. SELECT ARRAY['ef1e0638-072e-4caa-88b3-97bfa5b2e8c3']::uuid[]
Craig Ringer
3

W kolejności preferencji: 4,1,2,3 Nie używaj UUID jako klucza klastrowania, jeśli używasz serwera SQL, ponieważ nie tylko źle fragmentuje, klucz klastrowania jest używany we wszystkich indeksach nieklastrowanych i dodajesz te bajty do każdy wiersz indeksu. Fragmentację można złagodzić za pomocą NEWSEQUENTIALID, ale zwykle wolą tożsamość bingint dla Twojego klucza klastrowania niż GUID, aby zapobiec wzdęciom w innych indeksach.

Różnica między wyborem 1 na 2 zależy od tego, jak bardziej wydajna baza danych obsługuje dwie kolumny podstawowych typów w stosunku do stałej kolumny z jedną kolumną. Testowanie przy użyciu fałszywych danych powinno być dość łatwe. Sprawdź szybkość swoich zapytań, a także rozmiar indeksów i danych. Mały + szybki jest najlepszy!

GilesDMiddleton
źródło
1

Należy przypuszczać, że każdy typ danych obsługiwany natywnie byłby lepiej zoptymalizowany w produkcie niż cokolwiek, co można by połączyć jako klienta tego produktu. Następnie cokolwiek ma najmniejszą liczbę bajtów, więc uzyskuje się maksymalną liczbę wierszy na stronę.

Michael Green
źródło
To prawda, ale czy liczy się tylko rozmiar bajtu? Czy typ nie wpływa na algorytm indeksowania?
Vlad Mihalcea
@Vlad Używam SQL Server. AFAIK wszystkie typy danych są obsługiwane tak samo podczas konstruowania drzewa B (lub indeksu skrótu dla 2104 w pamięci). Istnieją dobre powody, aby ograniczyć to do minimum.
Michael Green