Para uma tabela com coluna de identidade, um índice PK / exclusivo em cluster ou não em cluster deve ser criado para a coluna de identidade?
O motivo é que outros índices serão criados para consultas. Uma consulta que usa um índice não clusterizado (em um heap) e retorna colunas que não são cobertas pelo índice usará menos E / S lógica (LIO) porque não há etapas adicionais de busca de árvore b de índice clusterizado?
create table T (
Id int identity(1,1) primary key, -- clustered or non-clustered? (surrogate key, may be used to join another table)
A .... -- A, B, C have mixed data type of int, date, varchar, float, money, ....
B ....
C ....
....)
create index ix_A on T (A)
create index ix_..... -- Many indexes can be created for queries
-- Common query is query on A, B, C, ....
select A, B
from T
where A between @a and @a+5 -- This query will have less LIO if the PK is non-clustered (seek)
select A, B, C
from T
where B between @a and @a+5
....
A PK em cluster na coluna de identidade é boa porque:
Aumenta monotonamente para que nenhuma página seja dividida ao inserir. Dizem que uma inserção em massa pode ser tão rápida quanto em uma tabela de pilha (não clusterizada)
É estreito
No entanto, as consultas na pergunta serão mais rápidas sem a configuração em cluster?
** Atualização: ** E se o Id
FK for de outras tabelas e ele for associado a algumas consultas?
Respostas:
Por padrão, o PK está agrupado e, na maioria dos casos, isso é bom. No entanto, qual pergunta deve ser feita:
PK e índice clusterizado são duas coisas diferentes:
Agora, terminamos com duas perguntas:
Depende de como:
Primeiro, você precisa de um índice em cluster? Se você inserir em massa, é mais eficiente armazenar dados não ordenados em um HEAP (versus dados ordenados em um cluster). Ele usa o RID (identificador de linha, 8 bytes) para identificar exclusivamente as linhas e armazená-las nas páginas.
O índice clusterizado não deve ser um valor aleatório. Os dados no nível da folha serão armazenados e ordenados pela chave de índice. Portanto, ele deve crescer continuamente para evitar fragmentação ou divisão de página. Se isso não puder ser alcançado pela PK, considere outra chave como candidato em cluster. O índice agrupado nas colunas de identificação, o GUID seqüencial ou mesmo algo como a data da inserção é bom do ponto de vista seqüencial, pois todas as linhas serão adicionadas à última página de folha. Por outro lado, embora o identificador exclusivo possa ser útil para as necessidades da sua empresa como PK, eles não devem ser agrupados (eles são ordenados / gerados aleatoriamente).
Se, após algumas análises de dados e consultas, você descobrir que usa o mesmo índice para obter seus dados antes de fazer uma pesquisa de chave na PK em cluster, considere-o como índice em cluster, embora possa não identificar exclusivamente seus dados.
A chave de índice em cluster é composta por todas as colunas que você deseja indexar. Uma coluna uniquefier (4 bytes) será adicionada se não houver restrição exclusiva nela (valor incremental para duplicatas, nulo caso contrário). Essa chave de índice será armazenada uma vez para cada linha no nível da folha de todos os seus índices não clusterizados. Alguns deles também serão armazenados várias vezes em níveis intermediários (ramificação) entre a raiz e o nível das folhas da árvore de índice (árvore B). Se a chave for muito grande, todo o índice não clusterizado ficará maior, exigirá mais armazenamento e mais IO, CPU, memória, ... Se você tiver um PK em nome + data de nascimento + país, é muito provável que essa chave não é um bom candidato. É muito grande para um índice em cluster. O identificador exclusivo usando NEWSEQUENTIALID () geralmente não é considerado uma chave estreita (16 bytes), embora seja seqüencial.
Depois que você descobrir como identificar linhas exclusivamente em sua tabela, poderá adicionar uma PK. Se você acha que não o usará em sua consulta, não o crie em cluster. Você ainda pode criar outro índice não clusterizado se precisar, em algum momento, consultá-lo. Observe que o PK criará automaticamente um índice exclusivo.
Os índices não agrupados sempre conterão a chave agrupada. No entanto, se as colunas indexadas (+ colunas principais) estiverem cobrindo, não haverá nenhuma pesquisa de chave no índice clusterizado. Não esqueça que você também pode adicionar Incluir e Onde a um índice não agrupado. (use-o com sabedoria)
O índice de cluster deve ser único e o mais estreito possível. O índice de cluster não deve mudar ao longo do tempo e deve ser inserido de forma incremental.
Agora é hora de escrever um pouco de SQL que criará a tabela, índices e restrições em cluster e não em cluster.
Isso tudo é teórico, porque não conhecemos seu modelo de dados e tipos de dados usados (A e B).
fonte
Se você está perguntando se o padrão de uma chave primária em uma coluna de identidade (em particular) deve ser não clusterizado, eu diria que não. A maioria das tabelas se beneficia de ter um índice em cluster, portanto, tornar o cluster o padrão para uma restrição de chave primária provavelmente é útil em geral, especialmente para novos usuários do SQL Server.
Como em praticamente qualquer opção, sempre existem circunstâncias diferentes em que uma deve ser preferida à outra, mas um DBA experiente deve estar ciente do padrão e substituí-lo quando apropriado. Consulte também as perguntas e respostas relacionadas: Quando uma chave primária deve ser declarada sem cluster? .
Sim, mas com ressalvas.
As pesquisas de RID são realmente mais eficientes do que as principais pesquisas. Mesmo que todas as páginas necessárias estejam na memória (provavelmente para os níveis superiores de um índice), há um custo de CPU associado à navegação na árvore b do índice em cluster. Como conseqüência, o SQL Server normalmente pode executar muito mais pesquisas de RID do que pesquisas de chave por unidade de tempo de CPU.
Ressalvas
O exposto acima não costuma ser um fator determinante na decisão de estruturar uma tabela como uma pilha ou não. Teria que ser impraticável para evitar pesquisas (usando índices de cobertura), e o número de pesquisas teria que ser grande o suficiente para ter um efeito mensurável (e importante) no desempenho, considerando o ambiente de hardware e a carga de trabalho.
Não é realmente prático abordar todos os aspectos do debate sobre heap versus índice de cluster nesta resposta, mas direi que há relativamente poucas boas razões para preferir estruturar uma tabela como heap em geral. Para mim, escolher o tipo de design proposto na pergunta exigiria uma análise muito cuidadosa antes da implementação e teria que atender a um nível alto. Argumentos gerais sobre 'escalabilidade' não seriam suficientes.
Com relação à atualização da pergunta sobre junções, avaliar o impacto da perda do índice clusterizado nos planos de execução faria parte da análise mencionada acima. Se junções de loops aninhados forem usadas, é muito conveniente ter o índice de cluster na chave de junção, porque todas as colunas da linha estarão imediatamente disponíveis sem uma pesquisa.
Minha própria experiência foi que ter índices clusterizados exclusivos em colunas de identidade é muitas vezes benéfico, todas as coisas são consideradas. Eu achei os montes problemáticos em termos de gerenciamento de espaço e também devo mencionar que alguns recursos do SQL Server exigem um índice clusterizado exclusivo para funcionar.
fonte
Na verdade, você não precisa de um Índice de Cluster nem uma Chave Primária para ser criado, pois Índices Exclusivos e Índices Não Exclusivos podem lidar com o trabalho. O SQL Server oferece suporte a um índice clusterizado desde pelo menos a versão 1.1, mas a chave primária era apenas um "conceito" que os programadores aplicaram ao definir um índice exclusivo.
Mas parece que as Chaves Primárias e os Índices em Cluster são conceitos valiosos na maioria dos bancos de dados.
Vejamos a documentação do SQL Server para ver as descrições parciais de algumas opções de indexação, como mostrado abaixo.
Índice agrupado: https://msdn.microsoft.com/en-us/library/ms190457.aspx
Chave primária: https://msdn.microsoft.com/en-us/library/ms190457.aspx
Uma tabela pode conter apenas uma restrição PRIMARY KEY.
Todas as colunas definidas em uma restrição PRIMARY KEY devem ser definidas como NOT NULL.
A chave primária pode ser criada como um índice clusterizado (o padrão se não houver índice clusterizado) ou um índice não clusterizado.
Índice exclusivo: https://msdn.microsoft.com/en-us/library/ms187019.aspx
Quando você cria uma restrição UNIQUE, um índice exclusivo não clusterizado é criado para impor uma restrição UNIQUE por padrão.
Você pode especificar um índice clusterizado UNIQUE se um índice clusterizado ainda não existir para a tabela.
Isso significa que sua pergunta sobre índices clusterizados e chaves primárias é realmente sobre alguns dos seguintes problemas. Observe que nem todas as tabelas se beneficiam do mesmo plano de indexação.
Quando eu me beneficiaria com a Chave Primária separada do Índice de Cluster?
Talvez quando o Índice de Cluster seja Amplo (por exemplo, 5 colunas de informações textuais, mas a Chave Primária é pequena (INT ou BIGINT), como você parece estar descrevendo.
Você deve tornar a Chave Primária sozinha o Índice de Cluster?
Se você possui uma Chave Primária pequena (INT ou BIGINT) e é o Índice de Cluster, a sobrecarga das colunas do cluster é relativamente pequena. Embora a Chave Primária em Cluster neste caso também exista em todos os índices desta tabela, é um preço menor a pagar do que o Wide Cluster discutido acima.
Esse índice de cluster de chave primária geralmente não oferece diretamente um caminho fácil para a seleção serial de muitas linhas.
Agora que você criou uma Chave Primária em Cluster, e as outras colunas que planejava incluir no Índice em Cluster ?
Crie um índice Exclusivo (ou Não Exclusivo) conforme necessário para indexar esse amplo critério de pesquisa das colunas C1, C2, C3, C4, C5. Os valores neste índice "Imitation Clustered" podem servir como um caminho de pesquisa mais rápido para essas 5 colunas. Se houver uma coluna ou duas não indexadas que também são selecionadas regularmente, elas podem ser incluídas no índice com
INCLUDE (Doctor_Name, Diagnosis_Synopsis)
.Embora eu ache úteis os Índices em Cluster e as Chaves Primárias simples, existem algumas boas razões para pensar em usá-los em uma tabela ou em um banco de dados.
Você precisa de um índice de cluster?
Se você criar índices (índices exclusivos e índices não exclusivos) e definir a chave primária sem a sobrecarga de ser um índice clusterizado, poderá descobrir que os índices mais restritos fornecem o que você precisa para suas consultas.
Existem alguns comportamentos úteis nos índices clusterizados e nas chaves primárias, mas lembre-se de que são realmente os índices que mais importam. Projete a estratégia de indexação para levar em conta as realidades do seu aplicativo. Talvez seja
OneBigTable
necessário ter uma estratégia de indexação diferente da usada na maioria das tabelas.Sem um índice agrupado, seus dados serão armazenados como um heap com o Row Identifier (RID), que não é um bom mecanismo de pesquisa. Mas, como mencionado anteriormente, você pode criar índices únicos e não exclusivos para lidar com suas consultas.
O que agora leva você a considerar Heaps:
Montes e índices: https://msdn.microsoft.com/en-us/library/hh213609.aspx
Mas se você também possui alguns 'pontos de acesso' em um grande conjunto de dados, também pode procurar outro tipo de índice:
Índice Filtrado: https://msdn.microsoft.com/en-us/library/cc280372.aspx
Um índice filtrado bem projetado melhora o desempenho da consulta e a qualidade do plano de execução, porque é menor que um índice não clusterizado de tabela completa e possui estatísticas filtradas. As estatísticas filtradas são mais precisas que as estatísticas de tabela completa porque cobrem apenas as linhas no índice filtrado .
Os índices filtrados têm várias restrições descritas no link para índices filtrados.
No entanto, se você estiver interessado em pensar nessa possibilidade de ignorar Chaves Primárias e Índices em Cluster, leia a publicação de Markus Winand no link abaixo. Ele demonstra seus motivos, com alguns exemplos de código, para sugerir que às vezes é uma boa ideia deixar de usar esses recursos.
http://use-the-index-luke.com/blog/2014-01/unreasonable-defaults-primary-key-clustering-key
Mas tudo finalmente volta a entender seu aplicativo e projetar o código, as tabelas, os índices e assim por diante para se adequar ao trabalho que você está fazendo.
fonte
Alguns pontos a considerar.
Embora um índice (agrupado ou não) em um valor crescente monótono economize as divisões de página durante inserções em massa, ele cria um novo ponto de acesso no final do índice. Embora possa não ser um problema com uma inserção em massa de um único encadeamento, definitivamente aumentará a contenção para um aplicativo multithread inserindo novas tuplas a uma taxa alta, pois os encadeamentos competirão constantemente pelo acesso à última página do índice.
Agrupar a tabela com base em uma PK substituta (identidade) raramente é benéfico. Essa chave primária é usada principalmente para acessar tuplas individuais, uma de cada vez, ou verificar o índice inteiro em busca de junções. Em ambos os casos, não importa se o índice está em cluster ou não (com exceção das junções de mesclagem, pode ser, mas com que frequência elas são?)
Acho que você se beneficiará mais de um índice agrupado que cobre consultas que solicitam uma verificação de intervalo de chaves e predicados adicionais referentes a outras colunas.
fonte