Quais são as considerações de desempenho entre o uso de uma PK ampla versus uma chave sintética separada e a UQ?

10

Eu tenho várias tabelas nas quais os registros podem ser identificados exclusivamente com vários campos comerciais amplos. No passado, eu usei esses campos como um PK, com esses benefícios em mente:

  • Simplicidade; não há campos estranhos e apenas um índice
  • O agrupamento permite junções de mesclagem rápidas e filtros baseados em intervalo

No entanto, ouvi um argumento para criar uma IDENTITY INTPK sintética e aplicar a chave comercial com uma UNIQUErestrição separada . A vantagem é que o PK estreito gera índices secundários muito menores.

Se uma tabela não tiver outros índices além da PK, não vejo motivo para favorecer a segunda abordagem, embora em uma tabela grande provavelmente seja melhor supor que os índices possam ser necessários no futuro e, portanto, favorecer a PK sintética estreita . Estou faltando alguma consideração?

Aliás, não estou argumentando contra o uso de chaves sintéticas em data warehouses, apenas estou interessado em quando usar uma única PK ampla e quando usar uma PK estreita mais um amplo Reino Unido.

Jon de todos os comércios
fonte
11
você pode encontrar este ou esta útil entre outras perguntas no site
Jack diz tentar topanswers.xyz

Respostas:

11

Não há desvantagem significativa usando a chave natural como o índice clusterizado

  • não há índices não agrupados em cluster
  • nenhuma chave estrangeira referenciando esta tabela (é uma linha pai)

A desvantagem seria o aumento de divisões de páginas, pois as inserções de dados seriam distribuídas pelos dados, em vez de no final.

Onde você tem índices FKs ou NC, o uso de um índice clusterizado estreito, numérico e crescente tem vantagens. Você repete apenas alguns bytes de dados por entrada NC ou FK, e não a chave comercial / natural while.

Sobre o motivo, leia os 5 artigos do Google

Nota: evitei o uso de "chave primária".

Você pode ter o índice em cluster na chave substituta, mas manter a PK nas regras de negócios, mas como não em cluster. Apenas certifique-se de que o cluster seja único porque o SQL adicionará um "uniquificador" para fazê-lo.

Finalmente, pode fazer sentido ter uma chave substituta, mas não cegamente em todas as tabelas : muitas tabelas não precisam de uma ou onde uma chave composta das tabelas pai será suficiente

gbn
fonte
+1 para a referência Sra. Tripp excelentes artigos em indexação.
Fabricio Araujo 13/10
2
+1 para que o desempenho não tenha nada a ver com chaves primárias e tudo tenha a ver com índices.
Nvogel
4

Embora eu arrisque afirmar o óbvio, um índice em uma chave substituta (um número de identificação) é útil se você precisar localizar as coisas pelo número de identificação. Os usuários não vão lidar com o número de identificação; eles vão lidar com texto legível por humanos. Portanto, você precisa repassar muito o texto e seu número de identificação, para que a interface do usuário possa exibir o texto e operar com o número de identificação.

Os dbms usarão esse tipo de índice para suportar chaves estrangeiras, se você as definir dessa maneira.

Às vezes, você pode melhorar o desempenho usando números de identificação como chaves estrangeiras, mas não é uma melhoria absoluta. Em nosso sistema OLTP, chaves estrangeiras que usam chaves naturais superaram as chaves estrangeiras usando números de identificação em um conjunto de testes de cerca de 130 (eu acho) consultas representativas. (Como as informações importantes geralmente são carregadas nas chaves, o uso de chaves naturais evitou muitas junções.) A aceleração mediana foi um fator de 85 (as junções usando números de identificação demoraram 85 vezes mais para retornar as linhas).

Os testes mostraram que as junções nos números de identificação não teriam desempenho mais rápido do que as leituras nas chaves naturais em nosso banco de dados até que determinadas tabelas atingissem muitos milhões de linhas. A largura da linha tem muito a ver com isso - linhas mais largas significam menos linhas cabidas em uma página, então você precisa ler mais páginas para obter 'n' linhas. Quase todas as nossas mesas estão em 5NF; a maioria das mesas é bastante estreita.

Quando as junções começam a executar leituras simples aqui , colocar tabelas e índices críticos em um disco de estado sólido pode nivelar o desempenho em centenas de milhões de linhas.

Mike Sherrill 'Rechamada de gato'
fonte
3

Eu tenho um banco de dados oltp inteiro projetado usando colunas de identidade para clustering + pk. Ele funciona muito rápido na inserção / procura, mas já vi alguns problemas:
1. a opção de preenchimento do índice é inútil porque as inserções acontecem apenas no final do índice
2. mais espaço de armazenamento. Eu tenho tabelas com dezenas de milhões de registros e 1 int ocupa espaço por si só. Cada tabela com uma coluna de identidade para o pacote tem que ter outro índice para buscas de negócios, para que seja necessário ainda mais armazenamento.
3. escalabilidade. Este é o pior problema. Como cada inserção vai para o final do índice, cada inserção enfatiza apenas o final do índice (alocação, io para gravações etc.). Usando uma chave comercial como chave de cluster, você pode distribuir as inserções uniformemente no índice. Isso significa que você acabou de eliminar um grande hotspot. Você pode facilmente usar mais arquivos para um índice, cada arquivo em uma unidade separada, cada unidade funcionando separadamente.

Comecei a mudar minhas tabelas de colunas de identidade para chaves naturais (talvez separadas para clustering e pk). Parece melhor agora.

Eu sugeriria o seguinte (pelo menos para um oltp db):
1. use como chave de cluster as colunas corretas na ordem certa para otimizar as consultas mais frequentes
2. use um pk nas colunas corretas que fazem sentido para sua tabela

Se a chave de cluster não é simples e contém chars (char [], varchar, nvarchar), acho que a resposta é 'depende', você deve analisar individualmente cada caso.

Eu mantenho o seguinte princípio: otimizar para a consulta mais comum, minimizando o pior cenário possível.

Eu quase esqueci um exemplo. Eu tenho algumas tabelas que se referem a si mesmas. Se essa tabela tiver uma coluna de identidade para sua chave primária, a inserção de uma linha poderá exigir uma atualização, e a inserção de mais de uma linha por vez pode ser difícil, se não impossível (depende do design da tabela).

Catalin Adler
fonte
4
Seu conceito de "ponto de acesso" é um mito: dba.stackexchange.com/questions/1584/… E quando você diz "Parece que está melhor agora". você fez benchmark?
gbn 4/10/11
4
Sim, as gravações são feitas na memória e não diretamente no disco. Se você gravar 20 novas linhas em uma página, haverá apenas 1 gravação física no arquivo de dados quando o ponto de verificação ocorrer.
mrdenny
O @mrdenny com inserções suficientes escrevendo tudo no final do índice enviaria todas as solicitações de gravação io para o mesmo arquivo. Suspeito que usando transações oltp normais esse cenário seja difícil de reproduzir, mas usando alguns cenários especiais, como registros de inserção em massa / lote, o uso de ssis para mover alguns dados comerciais o levará até lá.
Catalin Adler 04/10
11
@ user973156 sim, todos os pedidos fariam no mesmo arquivo, mas as gravações não vão realmente para o disco até o ponto de verificação, o que acontece apenas a cada minuto (por padrão) ou quando o buffer de gravação está 50% cheio. Não importa como você escreve os dados, esta regra ainda se aplica.
mrdenny
2
@ user973156 A utilização de uma chave de cluster distribuída aleatoriamente causará fragmentação do índice. A fragmentação do índice causará problemas de desempenho. E sua tabela ficará grande o suficiente para que a desfragmentação do índice demore "muito tempo" e consuma espaço de log e potencialmente espaço tempDB. Quando tenho pessoas como Kimberly Tripp me dizendo que é uma boa ideia, eu ouço. ( sqlskills.com/BLOGS/KIMBERLY/post/… )
Matt M
2

Do ponto de vista do desempenho, a escolha de qual chave é a chave "primária" não faz nenhuma diferença. Não há diferença entre usar uma PRIMARY KEY e uma restrição UNIQUE para aplicar suas chaves.

O desempenho é determinado pela seleção e tipo de índices e outras opções de armazenamento e pela maneira como as chaves são usadas em consultas e códigos.

nvogel
fonte