Como criar visões materializadas no SQL Server?

101

Vou desenhar um DW e ouvi falar de visões materializadas. Na verdade, eu quero criar uma visão e ela deve atualizar automaticamente quando as tabelas base são alteradas. Alguém pode explicar com um exemplo de consulta ..

Deepak
fonte

Respostas:

144

Eles são chamados de visualizações indexadas no SQL Server - leia estes documentos para obter mais informações básicas:

Basicamente, tudo que você precisa fazer é:

  • criar uma visão regular
  • crie um índice clusterizado nessa vista

e pronto!

A parte complicada é: a visualização deve satisfazer uma série de restrições e limitações - aquelas são descritas no white paper. Se você fizer isso - é tudo o que existe. A visualização está sendo atualizada automaticamente, sem necessidade de manutenção.

Recursos adicionais:

marc_s
fonte
Obrigado pela sua resposta. Consegui o que quero .. Gostaria de saber sobre os índices também. Eu quero saber se existe alguma maneira de gerar o diagrama de esquema em estrela no servidor SQL quando eu tiver toda a estrutura da tabela pronta? Se sim, como crio uma tabela de fatos para isso?
Deepak
3
As restrições para colocar um índice clusterizado na exibição são extensas. Por exemplo, a visualização não pode fazer referência a outras visualizações e não pode conter junções externas. Portanto, muitas visualizações que precisam de melhor desempenho não podem usar esse método. Ainda é uma boa resposta.
Jeff Wilson
1
Conforme mencionado em uma pergunta relacionada, o artigo do blog do MSDN, blogs.msdn.microsoft.com/ssma/2011/06/20/… , destaca algumas das principais diferenças entre exibições materializadas e exibições indexadas. O mais problemático IMHO é não ser capaz de especificar gatilhos de atualização: as visualizações indexadas são atualizadas sempre que as tabelas base são atualizadas - minando a maioria dos benefícios de desempenho do uso de uma visualização materializada. Proibições em junções, agregações, funções de janelas e subconsultas tornam as visualizações indexadas quase inúteis, a menos que os dados não mudem com frequência.
Suncat2000
43

Embora puramente da perspectiva da engenharia, as visualizações indexadas parecem algo que todos poderiam usar para melhorar o desempenho, mas o cenário da vida real é muito diferente. Não tenho tido sucesso usando exibições indexadas onde mais preciso, devido a muitas restrições sobre o que pode ser indexado e o que não pode.

Se você tiver junções externas nas visualizações, elas não podem ser usadas. Além disso, expressões de tabela comuns não são permitidas ... Na verdade, se você tiver qualquer ordenação em subseleções ou tabelas derivadas (como partição por cláusula), você também está sem sorte.

Isso deixa apenas cenários muito simples para utilizar visualizações indexadas, algo na minha opinião pode ser otimizado criando índices apropriados em tabelas subjacentes de qualquer maneira.

Ficarei emocionado em ouvir alguns cenários da vida real em que as pessoas realmente usaram visualizações indexadas para seu benefício e não poderiam ter passado sem elas

Rajiv
fonte
Na verdade, usei exibições indexadas (apenas uma vez) para particionar um índice de pesquisa de texto completo. Os índices FTS de fato não podem ser particionados, mas índices separados podem ser criados em várias visualizações da mesma tabela. No entanto, era uma espécie de último recurso.
areyesram de
4
Você precisa se lembrar de adicionar (NOEXPAND)dicas às consultas que usam as visualizações indexadas. E então você percebe a diferença. A vantagem de usar as visualizações indexadas versus "indexar corretamente as tabelas" é limitar a seleção de registros, caso contrário, você está correto, seria o mesmo.
ajeh de
Sim, o NOEXPAND não pode ser subestimado!
Simon_Weaver
18

Você pode precisar de um pouco mais de conhecimento sobre o que realmente é uma Visualização Materializada. No Oracle, eles são um objeto que consiste em vários elementos quando você tenta construí-lo em outro lugar.

Um MVIEW é essencialmente um instantâneo de dados de outra fonte. Ao contrário de uma visão, os dados não são encontrados quando você consulta a visão, eles são armazenados localmente em uma forma de tabela. O MVIEW é atualizado usando um procedimento em segundo plano que inicia em intervalos regulares ou quando os dados de origem são alterados. O Oracle permite atualizações completas ou parciais.

No SQL Server, eu usaria o seguinte para criar um MVIEW básico para (completar) atualizar regularmente.

Primeiro, uma visão. Isso deve ser fácil para a maioria, já que as visualizações são bastante comuns em qualquer banco de dados. Em seguida, uma tabela. Isso deve ser idêntico à visualização em colunas e dados. Isso armazenará um instantâneo dos dados de exibição. Em seguida, um procedimento que trunca a tabela e a recarrega com base nos dados atuais da visualização. Finalmente, um trabalho que aciona o procedimento para iniciá-lo.

Todo o resto é experimentação.

Jason A.
fonte
5
Seus comentários sobre o SQL Server estão incorretos - visões materializadas são coisas muito diferentes no Oracle e no SQL Server. No SQL Server, uma visualização com um índice clusterizado exclusivo (também conhecido como "visualização materializada") não pode e não pode ser atualizada pelo usuário, nem é armazenada em uma tabela separada criada pelo usuário - é sempre atualizada pelo durante as atualizações e nunca fica fora de sincronia. Não há necessidade de trabalho para armazenar um instantâneo dos dados.
ErikE,
10
O que o OP pediu é facilmente fornecido por uma exibição indexada. Essa é a coisa mais próxima que o SQL Server fornece nativamente de uma visão materializada do Oracle. No entanto, se você deseja / precisa replicar exatamente a maneira como funciona um Oracle MVIEW, Jason está certo. A abordagem de Jason também ajuda no mesmo cenário que os Oracle MVIEWs podem - por exemplo, fazer a atualização fora de horas de uma tabela de relatórios onde você se preocupa mais com a carga do banco de dados do que com a atualização da visualização (por exemplo, relatórios apenas sobre os números de ontem ...)
4

Quando a exibição indexada não é uma opção e atualizações rápidas não são necessárias, você pode criar uma tabela de cache de hack:

select * into cachetablename from myviewname
alter table cachetablename add primary key (columns)
-- OR alter table cachetablename add rid bigint identity primary key
create index...

em seguida, sp_rename view / table ou altere quaisquer consultas ou outras exibições que façam referência a ele para apontar para a tabela de cache.

agendar diariamente / noturno / semanal / outros itens de atualização como

begin transaction
truncate table cachetablename
insert into cachetablename select * from viewname
commit transaction

NB: isso vai consumir espaço, também em seus logs tx. Melhor usado para pequenos conjuntos de dados que são lentos para computar. Talvez refatorar para eliminar colunas "fáceis, mas grandes" primeiro em uma visão externa.

Stox
fonte
1

Para o MS T-SQL Server, sugiro criar um índice com a instrução "incluir". A exclusividade não é necessária, nem a classificação física de dados associada a um índice clusterizado. O "Índice ... Incluir ()" cria um armazenamento de dados físicos separado mantido automaticamente pelo sistema. É conceitualmente muito semelhante a uma Visão Materializada Oracle.

https://msdn.microsoft.com/en-us/library/ms190806.aspx

https://technet.microsoft.com/en-us/library/ms189607(v=sql.105).aspx

Scott Nightlinger
fonte