Come creare viste materializzate in SQL Server?


101

Ho intenzione di progettare un DW e ho sentito parlare di viste materializzate. In realtà voglio creare una vista e dovrebbe aggiornarsi automaticamente quando vengono modificate le tabelle di base. Qualcuno può spiegare con un esempio di query ..

Risposte:


144

Si chiamano viste indicizzate in SQL Server: leggi questi white paper per ulteriori informazioni di base:

Fondamentalmente, tutto ciò che devi fare è:

  • creare una visualizzazione regolare
  • creare un indice cluster su quella vista

e hai finito!

La parte difficile è: la vista deve soddisfare un certo numero di vincoli e limitazioni, che sono delineati nel white paper. Se lo fai, è tutto quello che c'è. La visualizzazione viene aggiornata automaticamente, non è necessaria alcuna manutenzione.

Risorse addizionali:


Grazie per la tua risposta. Ho quello che voglio .. Vorrei sapere anche sugli indici. Voglio sapere che c'è un modo per generare il diagramma dello schema a stella nel server SQL quando ho tutta la struttura della tabella pronta? Se sì, come creo una tabella dei fatti per questo?
Deepak

3
Le restrizioni sull'inserimento di un indice cluster nella visualizzazione sono ampie. Ad esempio, la vista non può fare riferimento ad altre viste e non può contenere join esterni. Pertanto, molte visualizzazioni che richiedono prestazioni migliori non possono utilizzare questo metodo. Ancora una buona risposta.
Jeff Wilson,

1
Come menzionato in una domanda correlata, l'articolo del blog di MSDN, blogs.msdn.microsoft.com/ssma/2011/06/20/… , evidenzia alcune delle differenze principali tra le visualizzazioni materializzate e le visualizzazioni indicizzate. L'IMHO più problematico è non essere in grado di specificare i trigger di aggiornamento: le viste indicizzate vengono aggiornate ogni volta che le tabelle di base vengono aggiornate, minando la maggior parte dei vantaggi in termini di prestazioni dell'utilizzo di una vista materializzata. I divieti su join, aggregazioni, funzioni di windowing e sottoquery rendono le viste indicizzate quasi inutili a meno che i dati non cambino spesso.
Suncat 2000

43

Sebbene da un punto di vista puramente ingegneristico, le visualizzazioni indicizzate suonano come qualcosa che tutti potrebbero usare per migliorare le prestazioni, ma lo scenario della vita reale è molto diverso. Non ho avuto successo utilizzando le viste indicizzate dove ne ho più bisogno a causa delle troppe restrizioni su cosa può essere indicizzato e cosa no.

Se sono presenti join esterni nelle viste, non possono essere utilizzati. Inoltre, le espressioni di tabella comuni non sono consentite ... In effetti, se hai qualche ordinamento nelle sottoselezioni o nelle tabelle derivate (come con la clausola di partizione per), anche tu sei sfortunato.

Ciò lascia solo scenari molto semplici da utilizzare viste indicizzate, qualcosa a mio parere può essere ottimizzato creando comunque indici appropriati sulle tabelle sottostanti.

Sarò entusiasta di ascoltare alcuni scenari di vita reale in cui le persone hanno effettivamente utilizzato le visualizzazioni indicizzate a proprio vantaggio e non avrebbero potuto farne a meno


In realtà ho usato le viste indicizzate (solo una volta) per partizionare un indice di ricerca di testo completo. Gli indici FTS in effetti non possono essere partizionati, ma è possibile creare indici separati su più viste dalla stessa tabella. Tuttavia, era una specie di ultima risorsa.
areyesram

4
È necessario ricordarsi di aggiungere un (NOEXPAND)suggerimento alle query che utilizzano le viste indicizzate. E poi noti la differenza. Il vantaggio di utilizzare le viste indicizzate rispetto a "indicizzare correttamente le tabelle" sta nel limitare la selezione dei record, altrimenti hai ragione, sarebbe lo stesso.
ajeh

Sì, la cosa NOEXPAND non può essere sottovalutata!
Simon_Weaver

18

Potresti aver bisogno di un po 'più di background su cosa sia effettivamente una vista materializzata. In Oracle questi sono un oggetto che consiste in un numero di elementi quando si tenta di costruirlo altrove.

Un MVIEW è essenzialmente un'istantanea dei dati da un'altra fonte. A differenza di una vista, i dati non vengono trovati quando si interroga la vista, vengono memorizzati localmente in una forma di tabella. MVIEW viene aggiornato utilizzando una procedura in background che viene avviata a intervalli regolari o quando i dati di origine cambiano. Oracle consente aggiornamenti completi o parziali.

In SQL Server, utilizzerei quanto segue per creare un MVIEW di base per (completare) l'aggiornamento regolarmente.

Innanzitutto, una vista. Questo dovrebbe essere facile per la maggior parte poiché le visualizzazioni sono abbastanza comuni in qualsiasi database. Avanti, una tabella. Dovrebbe essere identico alla visualizzazione in colonne e dati. Ciò memorizzerà un'istantanea dei dati della vista. Quindi, una procedura che tronca la tabella e la ricarica in base ai dati correnti nella vista. Infine, un lavoro che attiva la procedura per avviare il suo lavoro.

Tutto il resto è sperimentazione.


5
I tuoi commenti su SQL Server non sono corretti: le viste materializzate sono cose molto diverse in Oracle e SQL Server. In SQL Server, una vista con un indice cluster univoco su di essa (detta anche "vista materializzata") non può e non può essere aggiornata dall'utente, né viene archiviata in una tabella separata creata dall'utente: viene sempre aggiornata dal motore durante gli aggiornamenti e non è mai fuori sincrono. Non è necessario alcun lavoro per memorizzare un'istantanea dei dati.
ErikE

10
Ciò che l'OP ha richiesto è facilmente fornito da una vista indicizzata. Questa è la cosa più vicina che SQL Server fornisce in modo nativo a una vista materializzata Oracle. Tuttavia, se vuoi / hai bisogno di replicare esattamente il modo in cui funziona un Oracle MVIEW, Jason ha ragione. L'approccio di Jason aiuta anche nello stesso scenario di Oracle MVIEWs, ad esempio facendo l'aggiornamento fuori orario di una tabella di report in cui ti interessa di più il carico del database rispetto a quanto è aggiornata la vista (ad esempio, riportando solo i numeri di ieri ...)

4

Quando la visualizzazione indicizzata non è un'opzione e non sono necessari aggiornamenti rapidi, puoi creare una tabella della cache di hacking:

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

quindi sp_rename view / table o modificare le query o altre visualizzazioni che fanno riferimento a esso in modo che punti alla tabella della cache.

programma giornaliero / notturno / settimanale / cosa non si aggiorna come

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

NB: questo consumerà spazio, anche nei tuoi log di trasmissione. Ideale per piccoli set di dati lenti da calcolare. Forse refactoring per eliminare prima le colonne "facili ma grandi" in una vista esterna.


1

Per MS T-SQL Server, suggerisco di cercare di creare un indice con l'istruzione "include". L'unicità non è richiesta, né l'ordinamento fisico dei dati associati a un indice cluster. L '"Index ... Include ()" crea un archivio dati fisico separato gestito automaticamente dal sistema. È concettualmente molto simile a una vista materializzata Oracle.

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

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.