Já tenho alguns milhões de linhas em meu banco de dados. Eu não sabia sobre o tipo de dados UUID do PostgreSQL quando projetei meu esquema.
Uma das tabelas tem 16 milhões de linhas (cerca de 3,5 milhões a 4 milhões de registros por estilhaço), crescendo cerca de 500 mil registros por dia. Ainda posso me dar ao luxo de desativar o sistema de produção por algumas horas, se necessário. Não terei esse luxo em uma ou duas semanas.
Minha pergunta é, será que vale a pena fazer isso? Estou me perguntando sobre o desempenho do JOIN, o uso do espaço em disco (o despejo gzip'd completo é de 1,25 GiB), coisas dessa natureza.
O esquema da tabela é:
# \d twitter_interactions
Table "public.twitter_interactions"
Column | Type | Modifiers
-------------------------+-----------------------------+-----------
interaction_id | character(36) | not null
status_text | character varying(1024) | not null
screen_name | character varying(40) | not null
twitter_user_id | bigint |
replying_to_screen_name | character varying(40) |
source | character varying(240) | not null
tweet_id | bigint | not null
created_at | timestamp without time zone | not null
Indexes:
"twitter_interactions_pkey" PRIMARY KEY, btree (interaction_id)
"twitter_interactions_tweet_id_key" UNIQUE, btree (tweet_id)
"index_twitter_interactions_on_created_at" btree (created_at)
"index_twitter_interactions_on_screen_name" btree (screen_name)
Triggers:
insert_twitter_interactions_trigger BEFORE INSERT ON twitter_interactions FOR EACH ROW EXECUTE PROCEDURE twitter_interactions_insert_trigger()
Number of child tables: 9 (Use \d+ to list them.)
Eu consideraria mudar para o tipo UUID.
char(36)
ocupa 40 bytes,uuid
ocupa 16, então você economizará 24 bytes por linha, o que para você equivalerá a 12 MB por dia, 4 GB após um ano. Mais índices. Dependendo do hardware que você possui, isso não é muito, mas pode ser. E isso aumenta se você tiver mais oportunidades de melhoria como essa.Além disso, não vejo nenhuma restrição em seu esquema que garanta que
interaction_id
esteja realmente no formato correto. Usar o tipo certo também lhe dará isso.Se você gosta disso, no entanto, usar
bigint
economizaria ainda mais e teria um desempenho ainda melhor. É muito improvável que seu aplicativo seja tão grande que umabigint
coluna para uma ID não funcione.Eu não sou uma pessoa postgres de forma alguma, mas com base no que eu sei do SQL Server, quanto mais linhas você puder colocar em uma página de dados, melhor desempenho você terá (a leitura de dados do disco é normalmente operação mais cara). Portanto, passar de um campo de 36 ish de 1 byte para um GUID de 16 bytes parece uma economia de custo direta. Quanto menos leituras você puder incorrer, mais rápido poderá retornar os resultados. Tudo isso obviamente pressupõe que um GUID/UUID satisfaça as necessidades de negócios da tabela. Se um UUID o satisfaz, um bigint ? Isso reduziria ainda mais seus custos de armazenamento em outros 8 bytes por linha.
Editar 1
Para dados de caracteres no Postgres, há um custo adicional de armazenamento para eles. Strings curtas, com menos de 127 bytes, têm uma sobrecarga de 1 byte, enquanto qualquer coisa maior tem 4 bytes, e foi assim que o segundo respondente apresentou um custo de 40 bytes para um campo de 36 bytes. Mas também há uma opção para compactação de string, então talvez não custe os 40 completos. Não posso dizer qual seria o custo final, mas os fundamentos permanecem: qualquer coisa acima de 16 bytes aumentará o custo de armazenamento, levará mais tempo para ler de e consumir mais memória.
Além do problema de espaço, lembre-se de que você precisará alterar todas as tabelas para usar o tipo de dados correto ou o desempenho da junção será ruim.
Além da economia de tamanho de dados e índices (como dito por outros), que se traduz em economia de E/S, o que você precisa considerar é como você gerará novos valores
interaction_id
e qual será o impacto no índices e condições de consulta (junções).Para o índice - será menor, no entanto, se muitas de suas consultas usarem varreduras de índice, a mudança para UUIDs pode tornar as varreduras de índice impossíveis (dependendo de como você gerará UUIDs) e
bigint
pode ser uma escolha muito melhor.Por fim, como o impacto real no desempenho também depende de seus padrões de uso e distribuição de dados, você deve executar testes e ter um ambiente de desenvolvimento e teste no qual possa testar suas alterações.
Isso lhe dará uma resposta muito mais exata sobre o impacto no desempenho.