Implicações do uso de um índice não clusterizado exclusivo com colunas de cobertura em vez de uma chave primária

12

Temos uma grande mesa [MyTable]que atualmente tem tanto um Primary Key, e um Unique Non Clustered Indexna mesma coluna ( [KeyColumn]). O índice U NC também possui colunas de cobertura adicionais.

Ter o PK e o índice NC exclusivo nas mesmas colunas parece redundante, então eu estava pensando em excluir a chave primária e, em vez disso, usar o índice exclusivo não clusterizado para fins de integridade referencial.

Observe que a tabela está totalmente agrupada por outra coluna.

Ou seja, temos:

ALTER TABLE [MyTable]
    ADD CONSTRAINT [PK_MyTable] 
    PRIMARY KEY NONCLUSTERED ([KeyColumn])
GO

E

CREATE UNIQUE NONCLUSTERED INDEX [IX_MyTable_SomeIndex] 
    ON [MyTable] ([KeyColumn]) 
    INCLUDE ([Column1], [Column2])
GO

Tanto quanto eu sei, não é possível adicionar colunas de cobertura a uma Chave Primária, então pretendo fazer:

  • Elimine as restrições de chave estrangeira dependentes MyTable.KeyColumn
  • Solte a Chave Primária MyTable.KeyColumninteiramente
  • Adicione novamente as chaves estrangeiras à tabela (ou seja, o RI será aplicado via MyTable.KeyColumn)

A única implicação que posso pensar em fazer isso é que não obteremos o símbolo da chave visual em nossos diagramas de ERD e que a densidade do índice (folha) será menor por causa das colunas incluídas.

Eu li /programming/487314/primary-key-or-unique-index e estou feliz com os aspectos de integridade e desempenho de fazer isso.

Minha pergunta é: essa abordagem é falha?

Editar O que estou tentando realizar : Otimização de desempenho e Limpeza de primavera . Ao remover o PK ou um Índice, haverá menos páginas necessárias para meus índices = gravações mais rápidas, além de benefícios operacionais / de manutenção, ou seja, um índice a menos para manter a desfragmentação etc.

Para colocar um pano de fundo nisso, eu nunca tive uma tabela que está sendo referenciada, sem um PK. No entanto, o fato de um índice NC com colunas de cobertura ter sido adicionado à tabela significa que eu preciso adaptar meu pensamento.

StuartLC
fonte
Você poderia comentar o que está tentando realizar? Você também deve ter um índice agrupado no final.
@ jn29098 - Atualizado. Confirmado que temos um índice clusterizado, em colunas que não são a PK nem as colunas de cobertura, portanto isso não parece relevante para esta decisão.
StuartLC 26/07/12
1
Você tem certeza de que não possui nenhuma ferramenta / modelagem de ORM / geração de dados que vomite quando vê o PK desaparecido?
Remus Rusanu
A única desvantagem que vejo é que, uma vez que o PK se foi ... então você tem apenas um índice na coluna-chave e as consultas que estão usando o índice PK dizem para verificação do índice na coluna-chave ou ordem por colunas-chave e que não são cobertas pelo índice Uniuqe, podem gerar um IO extra como páginas de folha índice exclusivo são muito mais do que a do PK.Otherwise parece fine.But alguns puristas dirão que você deve ter PK :)
Gulli Meel
1
Eu sugiro que você verifique a utilidade desse índice usando a DMV de estatísticas de uso do índice e verifique se ele está sendo usado por algumas de suas consultas. índice ..
Gulli Meel

Respostas:

3

Otimização de desempenho. Ao remover o PK ou um Índice, haverá menos páginas necessárias para meus índices = gravações mais rápidas, além de benefícios operacionais / de manutenção, ou seja, um índice a menos para manter a desfragmentação etc.

Você precisa provar que o que é proposto realmente ajuda (custo x benefício). Por que razão essa mudança está sendo considerada? Na verdade, existem problemas de desempenho com esta tabela ou apenas "pareceram errados"?

Aqui estão algumas outras perguntas que ajudarão você a tomar a melhor decisão para seu ambiente:

  • Quanto tempo seria economizado na janela de manutenção? Na janela de backup?

  • Quanto espaço de armazenamento isso economizaria (arquivos de dados, arquivos de log, backups etc.)?

  • O INSERTdesempenho nesta tabela é realmente um gargalo no momento? Quanto isso melhoraria? A remoção de um índice é a melhor estratégia para corrigir esse problema?

  • Isso causará problemas com ferramentas e estruturas de banco de dados (ORMs, em particular) que esperam que cada tabela tenha uma chave primária e não apenas um índice exclusivo? A replicação transacional requer uma chave primária nas tabelas publicadas.

  • Um esquema de banco de dados auto-documentado é importante?

  • Apesar do uso limitado, a restrição do índice de chave primária ainda permite que o otimizador produza planos mais eficientes para determinadas consultas? (Use sys.dm_db_index_usage_statspara descobrir.)

Pessoalmente, pelo que você nos disse, eu o deixaria em paz até que se prove que (a) o índice extra é um problema e (b) removê-lo é a solução.

Jon Seigel
fonte
Obrigado - verifica-se que as estatísticas do índice mostraram que o PK ainda era muito usado para verificações. Parece que eu estava sendo zeloso demais - os benefícios de legibilidade / convenção de manter a PK devem superar as implicações de armazenamento a longo prazo. No entanto, o argumento sobre a replicação transacional é decisivo - precisaremos replicar esse banco de dados em breve.
StuartLC
2

O único tipo de consulta nessa tabela que terá um desempenho pior (e apenas um pouco pior) será aquele que solicitar um intervalo de valores de KeyColumn - pois essas consultas no momento seriam melhor atendidas por uma pesquisa de índice em sua PK.

Vale lembrar que o custo da verificação da integridade referencial de tabelas que fazem referência a essa tabela será mais alto (novamente apenas levemente mais alto).

Contanto que você cuide do aspecto anulável, deve ficar bem com o único índice.

Se fosse meu banco de dados, eu provavelmente usaria o índice único e único, todas as outras coisas iguais.

Matt Whitfield
fonte
Obrigado - você tem algum link de referência? Se estiver um pouco pior, você está se referindo apenas à menor densidade de índice no índice de cobertura ou há algo mais que poderia causar isso?
StuartLC
Infelizmente, é de muita experiência e conversar com pessoas muito mais inteligentes do que eu ao longo dos anos! E sim, é precisamente isso - haverá menos linhas por página e mais E / S. No entanto - é importante notar que as colunas INCLUDE estão presentes apenas no nível da folha. Portanto, nem tudo é ruim. Tenho certeza que você sabe disso com base nos detalhes da sua pergunta, mas acho que outros leitores talvez não.
Matt Whitfield
-2

Até onde eu sei, não é possível adicionar colunas de cobertura a uma Chave Primária

Se você possui um índice em cluster no KeyColumn, como é um índice em cluster, todas as outras colunas são implicitamente 'cobertas'. Portanto, você não ganha nada adicionando outro índice no KeyColumn. De fato, você diminuirá a velocidade das inserções e utilizará mais espaço.

Isso ocorre porque um índice em cluster não é um índice como tal, mas apenas uma instrução para armazenar as linhas da tabela na ordem do índice. E depois de selecionar uma linha pela chave primária, você terá todas as outras colunas ali.

David Roussel
fonte
2
Desde o primeiro parágrafo:The table is clustered by another column entirely.
JNK
5
Eu acho que pode haver alguma confusão de chave primária / índice clusterizado acontecendo aqui. Apesar dos melhores esforços do estúdio de gerenciamento para convencê-lo, eles não são a mesma coisa.
Matt Whitfield