it-swarm-eu.dev

Výkon UUID v MySQL?

UUID hodnotíme jako primární klíče pro naši databázi MySQL. Vkládaná data jsou generována z desítek, stovek nebo dokonce tisíců vzdálených počítačů a jsou vkládána rychlostí 100-40 000 vložek za sekundu a nikdy nebudeme provádět žádné aktualizace.

Samotná databáze se obvykle dostane do přibližně 50M záznamů, než začneme vyřazovat data, takže ne masivní databáze, ale ani malá. Také plánujeme běžet na InnoDB, i když jsme otevřeni změnám, pokud je lepší motor pro to, co děláme.

Byli jsme připraveni jít s Java UUID typu 4, ale v testování bylo vidět nějaké podivné chování. Za prvé, my ukládáme jako varchar (36) a teď si uvědomuji, že bychom měli být lepší pomocí binárky (16) - i když si nejsem jistý.

Větší otázkou je: jak špatně tato náhodná data zkazí index, když máme 50M záznamy? Měli bychom být lepší, kdybychom použili například UUID typu 1, kde byly bitů nejvíce vlevo časově označeny? Nebo možná bychom měli ukořistit UUID úplně a zvážit primární klíče auto_increment?

Hledám obecné myšlenky/tipy na výkon různých typů UUID, když jsou uloženy jako index/primární klíč v MySQL. Dík!

70

V mé práci používáme UUID jako PK. Co vám mohu říci ze zkušenosti, NEPOUŽÍVEJTE je jako PK (mimochodem SQL Server).

Je to jedna z těch věcí, které když máte méně než 1000 záznamů, je to v pořádku, ale když máte miliony, je to to nejhorší, co můžete udělat. Proč? Protože UUID nejsou sekvenční, takže pokaždé, když je vložen nový záznam MSSQL musí jít podívat na správnou stránku vložit záznam a potom vložte záznam. Skutečným ošklivým důsledkem toho je, že stránky skončí v různých velikostech a skončí roztříštěné, takže nyní musíme dělat de-fragmentaci periodicky.

Když použijete autoincrement, MSSQL vždy přejde na poslední stránku a skončíte s stejně velkými stránkami (teoreticky), takže výkon pro výběr těchto záznamů je mnohem lepší (také proto, že INSERT nebude blokovat tabulku/stránku pro tak dlouho).

Velkou výhodou použití UUID jako PK je však to, že pokud máme shluky databází, při sloučení nebudou konflikty.

Doporučil bych následující model: 1. PK INT Identita 2. Další sloupec je automaticky generován jako UUID.

Tímto způsobem je možný proces sloučení (UUID by byl váš REAL klíč, zatímco PK by bylo jen něco dočasného, ​​které vám dává dobrý výkon).

POZNÁMKA: Nejlepším řešením je použít NEWSEQUENTIALID (jak jsem říkal v komentářích), ale pro starší aplikaci, která nemá moc času na refaktorování (a ještě horší, ne ovládání všech vložek), není možné. ____.] Ale opravdu od roku 2017 bych řekl, že nejlepší řešení zde je NEWSEQUENTIALID nebo dělá Guid.Comb s NHibernate.

Snad to pomůže

66
Kat Lim Ruiz

Je třeba vzít v úvahu, že Autoincrements jsou generovány po jednom a nelze je řešit paralelním řešením. Boj o použití UUID nakonec přijde na to, co chcete dosáhnout versus to, co potenciálně obětujete.

O výkonu, { krátce :

UUID, jako je ten výše, je dlouhý 36 Znaků, včetně pomlček. Pokud Uložíte tento VARCHAR (36), budete Dramaticky snižovat porovnávací výkon . Toto je váš primární Klíč, nechcete, aby to bylo pomalé.

Na své bitové úrovni je UUID 128 bitů, Což znamená, že se vejde do 16 bytů, Poznámka to není příliš čitelné pro člověka, , Ale bude udržovat úložiště nízké, a je pouze 4krát větší než 32bitová int, nebo 2krát větší než 64bitová int. Budu používat VARBINARY (16) Teoreticky to může fungovat bez Spoustu režijních nákladů.

Doporučuji přečíst následující dvě příspěvky:

Myslím, že mezi oběma, oni odpoví na vaši otázku.

25
Kyle Rozendo

Mám tendenci se vyhnout UUID jednoduše proto, že je to bolest uložit a bolest použít jako primární klíč, ale existují výhody. Hlavní z nich je UNIQUE. 

Obvykle jsem problém vyřešil a vyhnul se UUID pomocí dvou klíčů.

SBĚRATEL = JEDNODUCHÝ PŘIPOJENÝ K STROJI

ID = ZÁZNAM ZÍSKANÝ SBÍRATELEM (pole auto_inc)

To mi nabízí dvě věci. Rychlost auto-inc polí a jedinečnost dat jsou uloženy v centrálním místě po jejich shromáždění a seskupení. Vím také při procházení dat, kde byla shromážděna, což je často velmi důležité pro mé potřeby.

Viděl jsem mnoho případů, když jsem se zabýval jinými soubory dat pro klienty, kde se rozhodli použít UUID, ale pak mají stále pole, kde se data shromažďovala, což je skutečně plýtvání úsilím. Jednoduše pomocí dvou (nebo více v případě potřeby) polí, jak váš klíč opravdu pomáhá.

Právě jsem viděl příliš mnoho výkonových zásahů pomocí UUID. Cítí se jako cheat ...

5
Glenn J. Schworak

Namísto centrálního generování jedinečných klíčů pro každé vložení, jak o přidělování bloků klíčů jednotlivým serverům? Když jim dojde nedostatek klíčů, mohou požádat o nový blok. Pak řešíte problém režie připojením pro každou vložku.

Keyserver udržuje další dostupné id

  • Server 1 požaduje ID blok.
  • Keyserver vrátí (1,1000)
    Server 1 může vložit 1000 záznamů, dokud nebude muset požádat o nový blok
  • Server 2 požaduje indexový blok.
  • Keyserver vrátí (1001,2000)
  • atd...

Mohli byste přijít s sofistikovanější verzí, kde by server mohl požádat o počet potřebných klíčů, nebo vrátit nepoužité bloky na klíčový server, což by pak samozřejmě muselo zachovat mapu použitých/nepoužívaných bloků.

3
Bouke Versteegh

Každému serveru bych přiřadil číselný identifikátor transakčním způsobem. Pak každý vložený záznam pouze automaticky načte svůj vlastní čítač. Kombinace ServerID a RecordID bude jedinečná. pole může být indexováno a budoucí výběr výkonu založený na ServerID (v případě potřeby) může být mnohem lepší.

2
Nikolai

A co nějaký ručně vytvořený UID? Dejte každému z tisíců serverů ID a udělejte primární klíč combo klíč autoincrement, MachineID ???

1
MindStalker

Protože primární klíč je generován decentralizovaně, nemáte možnost použít auto_increment stejně.

Pokud nemusíte skrýt identitu vzdálených počítačů, použijte UUID typu 1 namísto UUID. Jsou snadnější generovat a přinejmenším neublíží výkonu databáze.

Totéž platí pro varchar (char, opravdu) versus binární: to může jen pomoci věci. Je to opravdu důležité, kolik výkonu se zlepšuje?

1
user3850

Krátká odpověď je, že mnoho databází má problémy s výkonem (zejména s vysokými svazky INSERT) v důsledku konfliktu mezi jejich metodou indexování a úmyslnou entropií UUID v bitech s vysokým řádem. Existuje několik běžných hacků:

  • zvolit jiný typ indexu (např. neclustered na MSSQL), který mu nevadí
  • munge data pro přesun entropie do bitů s nižším řádem (např. přeskupování bytů U1 UUID na MySQL)
  • uUID je sekundární klíč s primárním klíčem auto-inkrement int

... ale to jsou všechny hacky - a pravděpodobně křehké.

Nejlepší odpověď, ale bohužel nejpomalejší, je požadovat, aby váš dodavatel zdokonalil svůj produkt, aby se mohl zabývat UUID jako primárními klíči stejně jako jakýkoli jiný typ. Neměly by vás nutit k tomu, abyste si zkopírovali svůj napůl upečený hack, který by nahradil jejich neschopnost vyřešit to, co se stalo běžným případem použití, a bude i nadále růst.

0
StephenS