Por que as exibições indexadas não permitem índices agrupados não exclusivos?

12

Eu estive pensando em usar as Visualizações indexadas para aumentar o desempenho em algumas das visualizações mais usadas.

No entanto, as exibições indexadas não oferecem suporte a índices clusterizados não exclusivos, o que contraria um pouco a precedência definida pelo restante da estrutura do banco de dados.

Por exemplo, aqui está uma versão simplificada de algumas de nossas tabelas.

-Groups-
Group ID    GroupName

-Users-
UserKey    UserName    FullName     GroupID

Os índices estão em Groups.GroupID (não agrupado) e Users.GroupID (agrupado). A chave de cluster que está no GroupID na tabela Users, como geralmente um intervalo de usuários de um grupo específico, seria recuperada. Obviamente, você teria vários usuários por grupo, portanto esse índice em cluster não é exclusivo.

Isso me deixa um pouco incerto de como seguir essa precedência ao indexar minhas visualizações como este exemplo, pois não posso ter um índice em cluster não exclusivo.

ConsumableID    ConsumableVariantID AllowThresholdOverwrite FullPath    GroupID ManufacturerID  Type    ModelID
101              29                 1                       0.1.2.4.    4       3               3       2

Na realidade, o único valor nessa visualização que sempre seria exclusivo é a coluna ConsumableID, portanto, tenho poucas opções sobre onde colocar meu índice.

Por que os modos de exibição não permitem índices agrupados não exclusivos quando tabelas regulares o fazem?

Amigável
fonte
3
Há uma breve explicação no final desta página, intitulada 'Por que o primeiro índice de uma exibição precisa ser CLUSTERED e UNIQUE?' mas não faz muitos detalhes. Eu definitivamente ficaria interessado em ouvir uma explicação mais detalhada.
Steve Pettifer
5
Alguns comentários: 1 - Não há razão para você não se agrupar (GroupID, UserID). Não se limite a uma única coluna para a chave. 2 - Imagino que a limitação para uma visualização seja porque esse é um objeto de dados suplementares que precisa ter linhas facilmente vinculadas aos índices NC. Para uma tabela, a chave de IC não exclusiva recebe um int anexado a ela, mas acho que seria mais desafiador com uma exibição indexada, pois ela não é uma tabela real, mas precisa REFLECTAR uma tabela real.
JNK

Respostas:

22

A seguinte explicação é fornecida neste artigo técnico da Microsoft :

Por que o primeiro índice de uma exibição precisa ser CLUSTERED e UNIQUE?

Deve ser ÚNICO para permitir a pesquisa fácil de registros na visualização por valor-chave durante a manutenção indexada da visualização e impedir a criação de visualizações com duplicatas, o que exigiria uma lógica especial para manutenção. Ele deve estar em cluster porque apenas um índice em cluster pode impor exclusividade e armazenar as linhas ao mesmo tempo.

O SQL Server usa um sistema de álgebra delta para manter as exibições indexadas em sintonia com os dados de base. Ele também incorpora automaticamente operadores de plano de consulta de manutenção de exibição para cada consulta DML que afeta uma ou mais visualizações indexadas. Ter um índice clusterizado exclusivo na visualização simplifica bastante os detalhes da implementação.

O arranjo atual permite que as formas da árvore do operador de manutenção de forma fixa sejam incorporadas na árvore de consulta DML básica, fornecendo ortogonalidade que também simplifica o teste. Por fim, as exibições indexadas podem ser aprimoradas um dia para oferecer suporte a índices clusterizados não exclusivos, mas, novamente, tudo é possível com tempo ilimitado e recursos ilimitados (nenhum dos quais se aplica à equipe de desenvolvimento do SQL Server no momento da redação).

Para um exemplo que mostra como a construção do plano de consulta de atualização complexa pode ser obtida e a facilidade com que erros sutis podem surgir, consulte este exemplo de um erro que ocorre com MERGEíndices filtrados e filtrados (um recurso que tem uma estreita conexão com as visualizações indexadas).

Paul White 9
fonte
2
Um erro semelhante pode ocorrer se você tentar atualizar uma exibição indexada que possui uma GROUP BYcláusula, mas nem todas as expressões de agrupamento são chaves no índice clusterizado. É válido a partir do SQL Server 2014.
Quassnoi 08/10
4

No SQL Server, todas as chaves de índice devem ser internamente exclusivas. Isso é necessário para obter chaves de bloqueio que abordam exatamente uma linha. Também é necessário para a manutenção do índice. Imagine um NCI em uma coluna que tenha apenas um valor (100% de duplicatas). Se uma linha for excluída da tabela, o mecanismo de armazenamento deverá localizar a linha NCI correspondente e excluí-la também. Se todas as linhas NCI forem indistinguíveis, isso seria impossível.

Portanto, você vê que o IC em uma exibição deve ser (internamente) exclusivo para o mecanismo funcionar.

Se você não criar um índice exclusivo, o SQL Server ainda o tornará exclusivo internamente. No caso de um NCI em uma tabela de heap, ele anexa o marcador de linha. No caso de um IC não exclusivo, ele adiciona uma coluna de unificador. No caso de um NCI em uma tabela com um IC, ele anexa todas as colunas-chave do IC que você mesmo ainda não especificou (isso pode incluir o uniquificador).

Não existe uma coluna óbvia que possa ser anexada no caso de uma exibição indexada. Portanto, o SQL Server não pode fazer isso automaticamente.

Normalmente, é bastante óbvio para um ser humano quais colunas você pode adicionar para que a visualização tenha um conjunto exclusivo de colunas para usar no IC. Normalmente, essas são as colunas PK ou IC de uma das tabelas subjacentes. Se a visualização tiver um GROUP BYíndice normal nas chaves de agrupamento.

usr
fonte
2
Eu sugiro fortemente revisar o fraseado desta resposta. Embora contenha um ponto válido em relação à pergunta original, pode parecer que sugere que todos os índices não exclusivos contenham uniquificadores, o que não é o caso.
Spaghettidba
@ spaghettidba obrigado, eu não percebi isso. Espero que esteja melhor agora.
usr
Desculpe, ainda não. Você está misturando duas coisas. Os índices não clusterizados não precisam ser únicos e não são unificados internamente: você não está deixando claro esse ponto. Tudo o que você diz na sua resposta se aplica apenas a índices agrupados.
Spaghettidba
@spaghettidba Os NCIs são sempre únicos internamente. Eles sempre podem gerar todas as chaves de IC como parte de um plano de consulta. Consulte pastebin.com/vkGHpCsR A página de dados da NCI contém as duas colunas.
usr
Eu vejo de onde você está vindo. Várias folhas podem compartilhar a mesma chave de índice, mas a chave de cluster é sempre incluída nos NCIs. É suficiente dizer que eles sempre são únicos internamente? Acho que não.
Spaghettidba