A extensão sequential_uuid oferece dois geradores de UUID que produzem padrões sequenciais. Isso reduz a sobrecarga de E/S aleatória causada por UUIDs totalmente aleatórios em índices B-tree.
Geradores de UUID aleatórios (como UUID v4) distribuem valores uniformemente por todo o espaço de UUID. Cada inserção ocorre em uma página de folha de índice diferente, forçando o carregamento de todo o índice na memória quando seu tamanho excede o buffer compartilhado ou a RAM. Os UUIDs sequenciais resolvem esse problema ao garantir que novos valores sejam quase sempre anexados à extremidade direita do índice. Essa abordagem mantém o conjunto de trabalho ativo pequeno e melhora a taxa de acertos no cache.
Padrões sequenciais aumentam a previsibilidade dos UUIDs e a probabilidade de colisões entre máquinas. Para obter detalhes sobre as compensações de design, consulte Sequential UUID Generators .
Pré-requisitos
Antes de começar, verifique se o cluster PolarDB for PostgreSQL executa uma das versões secundárias do mecanismo compatíveis listadas abaixo.
Para verificar a versão atual, execute SHOW polardb_version; ou visualize-a no console. Caso o requisito de versão não seja atendido, atualize a versão secundária do mecanismo.
|
Versão do PostgreSQL |
Versão secundária mínima do mecanismo |
|
PostgreSQL 18 |
2.0.18.1.2.0 |
|
PostgreSQL 17 |
2.0.17.6.4.0 |
|
PostgreSQL 16 |
2.0.16.9.9.0 |
|
PostgreSQL 15 |
2.0.15.14.6.0 |
|
PostgreSQL 14 |
2.0.14.5.1.0 |
|
PostgreSQL 11 |
2.0.11.9.28.0 |
Como funciona
A extensão gera UUIDs em blocos. Cada UUID possui o formato (block ID, random data). O ID do bloco avança a cada novo bloco e eventualmente retorna ao início, equilibrando sequencialidade e aleatoriedade.
Uma abordagem ingênua — prefixar UUIDs com uma sequência bruta ou timestamp — cria dois problemas:
Aleatoriedade reduzida. O uso de uma sequência
bigintcomo prefixo diminui a parte aleatória de 16 bytes para 8 bytes. Isso aumenta a probabilidade de colisão e facilita a inferência do momento de geração dos UUIDs.Inchaço do índice. Valores monotonicamente crescentes fazem o índice crescer em uma única direção. A exclusão de linhas históricas deixa páginas mortas que nunca são reutilizadas.
O design baseado em blocos limita ambos os efeitos. Com o padrão de 65.536 blocos, o ID do bloco ocupa apenas 2 bytes, deixando os 14 bytes restantes como dados aleatórios. O ID do bloco retorna periodicamente, fazendo com que a gravação no índice ocorra em um padrão circular, em vez de linha reta.
Gerador baseado em sequência — fórmula do ID do bloco:
(nextval('s') / 256) % 65536
Com um tamanho de bloco de 256 UUIDs (conforme usado na chamada de exemplo), o gerador reinicia o ciclo a cada 16.777.216 UUIDs (256 x 65.536).
Gerador baseado em timestamp — fórmula do ID do bloco:
(timestamp / 60) % 65536
Considerando o intervalo padrão de 60 segundos e 65.536 blocos, o gerador reinicia o ciclo aproximadamente a cada 45 dias.
Ative a extensão
CREATE EXTENSION sequential_uuids;
Gere UUIDs sequenciais
A extensão fornece duas funções. Os valores padrão dos parâmetros funcionam bem para a maioria das cargas de trabalho.
uuid_sequence_nextval
Gera um UUID usando uma sequência do PostgreSQL para determinar o ID do bloco.
uuid_sequence_nextval(sequence regclass, block_size int DEFAULT 65536, block_count int DEFAULT 65536)
|
Parâmetro |
Tipo |
Padrão |
Descrição |
|
|
|
— |
Objeto de sequência usado para rastrear a posição |
|
|
|
|
Quantidade de UUIDs por bloco; o ID do bloco avança após esse número de UUIDs |
|
|
|
|
Número total de blocos; o gerador reinicia o ciclo após |
Exemplo — chamada independente:
CREATE SEQUENCE s;
SELECT uuid_sequence_nextval('s'::regclass, 256, 65536);
uuid_sequence_nextval
--------------------------------------
00005547-8a67-452d-bdf7-b390f1edc49b
(1 row)
Exemplo — uso como valor padrão de coluna:
CREATE SEQUENCE events_id_seq;
CREATE TABLE events (
event_id UUID PRIMARY KEY DEFAULT uuid_sequence_nextval('events_id_seq'::regclass),
event_type TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
uuid_time_nextval
Gera um UUID usando o timestamp atual para definir o ID do bloco.
uuid_time_nextval(interval_length int DEFAULT 60, interval_count int DEFAULT 65536)
|
Parâmetro |
Tipo |
Padrão |
Descrição |
|
|
|
|
Duração do bloco em segundos |
|
|
|
|
Total de blocos; o gerador reinicia o ciclo aproximadamente a cada |
Exemplo — chamada independente:
SELECT uuid_time_nextval(1, 256);
uuid_time_nextval
--------------------------------------
08dac705-8776-4ce3-a45c-123fd65e11e8
(1 row)
Exemplo — uso como valor padrão de coluna:
CREATE TABLE logs (
log_id UUID PRIMARY KEY DEFAULT uuid_time_nextval(),
message TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
Escolha um gerador
|
** |
** |
|
|
Limite do bloco |
A cada N UUIDs (configurável) |
A cada N segundos (configurável) |
|
Reinício do ciclo |
Após |
Após ~ |
|
Mais indicado para |
Cargas de trabalho de inserção com alto throughput |
Dados correlacionados por tempo; reinicia em um calendário previsível |
|
Dependência adicional |
Requer um objeto de sequência |
Nenhum objeto extra necessário |
Observações de uso
Os valores padrão dos parâmetros (
block_size = 65536,block_count = 65536,interval_length = 60) são adequados para a maioria das cargas de trabalho. Ajuste-os somente se houver requisitos específicos de throughput ou de reinício de ciclo.UUIDs sequenciais aumentam a previsibilidade em comparação aos UUIDs totalmente aleatórios. Evite utilizá-los em contextos onde a imprevisibilidade do UUID é um requisito de segurança.
O inchaço do índice causado pela exclusão de linhas históricas é reduzido, mas não eliminado. Operações periódicas de
VACUUMouREINDEXcontinuam sendo recomendadas para tabelas com altas taxas de exclusão.