Skip to main content

UUID v4, fragmentação de índice e por que UUID v7 melhora isso | UUID | CSharp

  • UUID v4, fragmentação de índice e por que UUID v7 melhora isso | UUID | CSharp

Uma crítica comum ao uso de UUID v4 como chave primária em bancos relacionais é o impacto que ele pode causar na estrutura física dos índices, especialmente em índices baseados em B-Tree.

O problema do UUID v4 em índices

O UUID v4 é essencialmente aleatório. Isso significa que, a cada novo registro inserido, o valor da chave primária pode cair em qualquer ponto lógico do índice.

Em bancos como PostgreSQL, MySQL/InnoDB e SQL Server, isso tende a gerar efeitos como:

  • menor localidade de escrita
  • páginas do índice sendo acessadas de forma mais dispersa
  • maior chance de page split
  • pior aproveitamento de cache
  • aumento de operações de I/O aleatório

Na prática, o banco não sofre porque o UUID é “grande” apenas. O problema principal é que a chave chega em ordem aleatória, o que dificulta inserções mais contíguas no índice.

Por que B-Trees preferem chaves ordenáveis

Estruturas de índice do tipo B-Tree funcionam melhor quando novos valores entram em ordem crescente ou aproximadamente crescente.

Exemplo de chave sequencial:

1001
1002
1003
1004

Nesse cenário, novas inserções tendem a ocorrer próximas do “fim” lógico do índice, reduzindo reorganizações internas.

Agora compare com chaves aleatórias:

8f2a...
13bc...
ff09...
4471...

Nesse caso, cada novo valor pode precisar ser inserido em posições muito diferentes da árvore, espalhando escrita e aumentando o custo de manutenção estrutural do índice.

O que isso pode causar na prática

Dependendo do volume e do padrão de escrita, usar UUID v4 pode levar a:

  • aumento de fragmentação
  • crescimento do índice acima do necessário
  • pior desempenho de inserção
  • pior desempenho de leitura indexada em alguns cenários
  • mais pressão em memória e disco

Esse efeito costuma ser mais perceptível quando:

  • a tabela é muito grande
  • há alta taxa de INSERT
  • a chave primária também é usada como índice clustered ou influencia fortemente a organização física dos dados
  • existem muitos índices secundários dependentes da PK

Onde entra o UUID v7

O UUID v7 foi projetado para manter a unicidade global, mas com uma característica importante: seus bits mais significativos carregam informação temporal.

De forma simplificada:

[ timestamp ][ versão ][ variante ][ aleatoriedade ]

Isso faz com que GUIDs gerados em momentos próximos tenham valores também próximos em ordem lexical/binária.

Resultado prático:

  • inserções mais previsíveis no índice
  • menor dispersão de escrita
  • melhor localidade
  • menos fragmentação do que UUID v4
  • comportamento mais amigável para B-Tree

UUID v7 é igual a um inteiro sequencial?

Não.

Ele não se comporta exatamente como um BIGINT IDENTITY, BIGSERIAL ou sequência monotônica pura.

Diferenças importantes:

  • continua tendo 128 bits
  • ainda possui parte aleatória
  • a ordenação é temporal, não necessariamente estritamente sequencial em todos os cenários
  • em sistemas distribuídos, clocks e concorrência podem introduzir pequenas variações

Mesmo assim, para o banco, o UUID v7 tende a ser muito melhor do que o UUID v4 quando o objetivo é reduzir fragmentação e melhorar a localidade de escrita.

Quando UUID v4 ainda pode ser aceitável

UUID v4 não é “errado”. Ele continua sendo uma opção válida quando:

  • a simplicidade importa mais do que a performance de índice
  • o volume de escrita não é alto
  • a tabela não é grande o suficiente para esse custo aparecer de forma relevante
  • a chave primária não é o principal gargalo da aplicação
  • o sistema já está consolidado e a troca não compensa

Ou seja: o problema não é “UUID v4 é proibido”. O problema é usar UUID v4 sem considerar o efeito físico que isso gera no banco.

Quando UUID v7 tende a ser a melhor escolha

UUID v7 costuma ser uma escolha melhor quando você quer:

  • IDs globais únicos
  • geração distribuída
  • melhor ordenação temporal
  • menor fragmentação de índice
  • melhor comportamento em banco do que UUID v4

Ele é especialmente interessante para:

  • sistemas de alta taxa de escrita
  • tabelas grandes
  • workloads intensivos em inserção
  • cenários em que a PK participa fortemente dos índices

Resumo prático

TipoUnicidade globalOrdenação temporalImpacto em índice
UUID v4SimNãoPior localidade, mais fragmentação
UUID v7SimSimMelhor localidade, menor fragmentação
BIGINT sequencialNão distribuído por naturezaSimMelhor comportamento para B-Tree

Conclusão técnica desta comparação

O comentário está certo ao afirmar que UUID v4 pode prejudicar o banco em comparação com identificadores ordenáveis. O ganho do UUID v7 está justamente em reduzir esse custo sem abrir mão da unicidade distribuída.

A forma mais precisa de dizer isso é:

UUID v4 resolve muito bem o problema de geração distribuída de IDs, mas pode degradar a eficiência dos índices devido à aleatoriedade. UUID v7 preserva a unicidade global e adiciona ordenação temporal, tornando-se mais adequado para bancos que usam B-Tree.