Estou depois de alguma confirmação dessa idéia para corrigir um banco de dados com desempenho ruim ou uma sugestão melhor, se alguém tiver um. Sempre aberto a melhores sugestões.
Eu tenho um banco de dados muito grande (mais de 20 milhões de registros crescendo cerca de 1/2 milhão por dia) que estão usando GUID como PK.
Uma supervisão da minha parte, mas o PK está agrupado no servidor SQL e está causando problemas de desempenho.
O motivo de um guia - esse banco de dados é parcialmente sincronizado com outros 150 bancos de dados, portanto a PK precisava ser única. A sincronização não é gerenciada pelo SQL Server, mas há um processo personalizado criado que mantém os dados sincronizados para os requisitos do sistema - todos baseados nesse GUID.
Cada um dos 150 bancos de dados remotos não armazena os dados completos armazenados no banco de dados SQL central. eles armazenam apenas um subconjunto dos dados que eles realmente precisam e os dados que eles exigem não são exclusivos deles (10 dos 150 bancos de dados podem ter alguns dos mesmos registros dos bancos de dados de outros sites, por exemplo - eles compartilham). Além disso - os dados são realmente gerados nos sites remotos - não no ponto central - daí a necessidade dos GUIDs.
O banco de dados central é usado não apenas para manter tudo sincronizado, mas as consultas de mais de 3000 usuários serão executadas nesse banco de dados fragmentado muito grande. Já é um grande problema nos testes iniciais.
Felizmente, ainda não estamos no ar - para que eu possa fazer alterações e colocar offline, se necessário, o que é pelo menos algo.
O desempenho dos bancos de dados remotos não é um problema - os subconjuntos de dados são bem pequenos e o banco de dados geralmente nunca ultrapassa 1 GB no total. Os registros são retornados ao sistema principal com bastante regularidade e removidos dos BDs menores quando não são mais necessários.
O desempenho do banco de dados central, que é o guardião de todos os registros, é lamentável - devido a um GUID em cluster como uma chave primária para muitos registros. A fragmentação do índice está fora dos gráficos.
Então - o meu pensamento para corrigir o problema de desempenho é criar uma nova coluna - IDENTIDADE BIGINT não assinada (1,1) e depois alterar o PK em cluster da coluna BIGINT da tabela.
Eu criaria um índice não clusterizado exclusivo no campo GUID, que era a chave primária.
Os 150 bancos de dados remotos menores não precisam saber sobre a nova PK no banco de dados do SQL Server Central - será puramente usada para organizar os dados no banco de dados e impedir o mau desempenho e a fragmentação.
Isso funcionaria e melhoraria o desempenho do banco de dados SQL central e impediria a fragmentação futura do índice (até certo ponto)? ou eu perdi algo muito importante aqui que vai pular e me morder e causar ainda mais sofrimento?
fonte
int
em 4255 dias (11,5 anos). Se ele fez isso, ele só culpá-lo em 11,5 anos;)Respostas:
Você certamente NÃO precisa se agrupar no GUID. Se você tiver algo que permita identificar exclusivamente os registros que não sejam esse GUID, sugiro que você crie um índice exclusivo nesse outro campo e torne esse índice agrupado. Caso contrário, você poderá agrupar em outros campos, mesmo usando índices não exclusivos. A abordagem que existe para agrupar, no entanto, facilita a divisão e a consulta de dados - portanto, se você tiver um campo "região", ou algo assim, que possa ser candidato ao seu esquema de agrupamento.
O problema de mudar para a
BIGINT
seria acrescentar dados de outros bancos de dados e integrar o banco de dados ao armazenamento central. Se isso não for uma consideração - e nunca será uma consideração -, sim,BIGINT
isso resolveria bem o problema de reequilíbrio do índice.Nos bastidores, se você não especificar um índice em cluster, o SQL Server fará a mesma coisa: ele cria um campo de ID de linha e mapeia todos os outros índices para ele. Então, fazendo você mesmo, você está resolvendo da mesma maneira que o SQL resolveria.
fonte
Essa é uma tarefa difícil.
Deixe-me sugerir uma abordagem intermediária.
Eu estava tendo problemas com System.Guid.NewGuid () gerando guias aleatórios. (Eu estava permitindo que o cliente criasse seu próprio guia, em vez de confiar no banco de dados para criar um sequencial).
Depois que mudei para um UuidCreateSequential no lado do cliente, meu desempenho ficou MUITO melhor, principalmente nos INSERTs.
Aqui está o código do cliente DotNet vodu. Tenho certeza de que penhorizei de algum lugar:
IDÉIA ALTERNATIVA:
Se o seu banco de dados principal e o banco de dados remoto estiverem "vinculados" (como em, sp_linkserver) ...... você poderá usar o banco de dados principal como o "gerador de uuid".
Você não quer ser "um por um" do uuid, isso é muita chats.
Mas você pode pegar um conjunto de uuids.
Abaixo está algum código:
/ *
* /
fonte
Com base na sua descrição, vá com BIGINT. No entanto, o índice para GUID pode não ser exclusivo, pois os GUIDs devem ser globalmente exclusivos de qualquer maneira.
fonte
Se o GUID for armazenado corretamente como identificador exclusivo, não deverá ter nenhum problema de desempenho ... e se você pode usar o GUID seqüencial ainda melhor ...
Também @mattytommo tem um bom ponto cerca de 11,5 anos com o uso de INT ...
fonte