Una vista è più veloce di una semplice query?


358

È un

select *  from myView

più veloce della query stessa per creare la vista (al fine di avere lo stesso set di risultati):

select * from ([query to create same resultSet as myView])

?

Per me non è del tutto chiaro se la vista utilizza una sorta di cache che la rende più veloce rispetto a una semplice query.


7
Non sono sicuro di una vista, ma le viste nidificate sono l'inferno delle prestazioni totali.
Muflix,

Risposte:


679

, alle viste può essere assegnato un indice cluster e, quando lo fanno, memorizzeranno i risultati temporanei che possono accelerare le query risultanti.

Aggiornamento: almeno tre persone mi hanno votato in questo senso. Con tutto il rispetto, penso che siano semplicemente sbagliati; La documentazione di Microsoft indica chiaramente che Views può migliorare le prestazioni.

In primo luogo, le viste semplici vengono espanse in atto e quindi non contribuiscono direttamente al miglioramento delle prestazioni - questo è vero. Tuttavia, le viste indicizzate possono migliorare notevolmente le prestazioni.

Lasciami andare direttamente alla documentazione:

Dopo aver creato un indice cluster univoco nella vista, il set di risultati della vista si materializza immediatamente e persiste nella memoria fisica nel database, risparmiando il sovraccarico di eseguire questa costosa operazione al momento dell'esecuzione.

In secondo luogo, queste viste indicizzate possono funzionare anche quando non sono direttamente referenziate da un'altra query poiché l'ottimizzatore le utilizzerà al posto di un riferimento di tabella quando appropriato.

Ancora una volta, la documentazione:

La vista indicizzata può essere utilizzata nell'esecuzione di una query in due modi. La query può fare riferimento direttamente alla vista indicizzata o, cosa ancora più importante, Query Optimizer può selezionare la vista se determina che la vista può essere sostituita per una parte o tutta la query nel piano di query più economico. Nel secondo caso, viene utilizzata la vista indicizzata al posto delle tabelle sottostanti e dei loro indici ordinari. Non è necessario fare riferimento alla vista nella query affinché Query Optimizer la utilizzi durante l'esecuzione della query. Ciò consente alle applicazioni esistenti di beneficiare delle viste indicizzate appena create senza modificarle.

Questa documentazione, nonché i grafici che dimostrano i miglioramenti delle prestazioni, sono disponibili qui .

Aggiornamento 2: la risposta è stata criticata sulla base del fatto che è l '"indice" che fornisce il vantaggio in termini di prestazioni, non la "Visualizzazione". Tuttavia, questo è facilmente confutato.

Diciamo che siamo una società di software in un piccolo paese; Userò la Lituania come esempio. Vendiamo software in tutto il mondo e conserviamo i nostri record in un database SQL Server. Abbiamo molto successo e quindi, tra qualche anno, abbiamo oltre 1.000.000 di dischi. Tuttavia, spesso dobbiamo segnalare le vendite a fini fiscali e scopriamo di aver venduto solo 100 copie del nostro software nel nostro paese di origine. Creando una vista indicizzata solo dei record lituani, riusciamo a conservare i record di cui abbiamo bisogno in una cache indicizzata come descritto nella documentazione di MS. Quando eseguiamo i nostri rapporti sulle vendite lituane nel 2008, la nostra query cercherà in un indice con una profondità di soli 7 (Log2 (100) con alcune foglie non utilizzate). Se dovessimo fare lo stesso senza la VISTA e basandoci solo su un indice nella tabella, dovremmo attraversare un albero indice con una profondità di ricerca di 21!

Chiaramente, la Vista stessa ci fornirebbe un vantaggio in termini di prestazioni (3x) rispetto al semplice utilizzo dell'indice da solo. Ho provato a usare un esempio del mondo reale, ma noterai che un semplice elenco di vendite lituane ci darebbe un vantaggio ancora maggiore.

Nota che sto solo usando un albero a b dritto per il mio esempio. Sebbene sia abbastanza certo che SQL Server utilizzi una variante di un b-tree, non conosco i dettagli. Tuttavia, il punto vale.

Aggiornamento 3: è emersa la questione se una vista indicizzata utilizza solo un indice posizionato nella tabella sottostante. Cioè, per parafrasare: "una vista indicizzata è solo l'equivalente di un indice standard e non offre nulla di nuovo o unico a una vista". Se questo fosse vero, ovviamente, l'analisi sopra sarebbe errata! Consentitemi di fornire un preventivo dalla documentazione Microsoft che dimostri perché penso che questa critica non sia valida o vera:

L'uso degli indici per migliorare le prestazioni delle query non è un nuovo concetto; tuttavia, le viste indicizzate offrono ulteriori vantaggi in termini di prestazioni che non possono essere raggiunti utilizzando gli indici standard.

Insieme alla citazione di cui sopra per quanto riguarda la persistenza dei dati nella memoria fisica e altre informazioni nella documentazione su come vengono creati gli indici su Views, penso che sia sicuro affermare che una vista indicizzata non è solo una selezione SQL memorizzata nella cache che utilizza un indice definito nella tabella principale. Pertanto, continuo a sostenere questa risposta.


29
Sì, le viste indicizzate possono migliorare notevolmente le prestazioni. Ma le viste indicizzate non sono solo "viste" e, in generale, le "viste" normali non sono più veloci delle loro query associate.
BradC,

10
@Charles - non importa se è l'indice, il fatto che una vista possa sfruttare l'indice e una query grezza non è sufficiente
annakata

194
/ applaude @Mark per aver difeso la sua posizione e aver litigato razionalmente
annakata,

17
Oh, amico, ho ottenuto 8 voti negativi su questo! Sono sorpreso che la gente avrebbe votato così in fretta senza almeno avere il coraggio di Charles di argomentare.
Mark Brittingham,

8
Poiché una tabella può avere solo un indice clusterdee e PUOI creare un indice cluster separato in una vista (poiché i campi nell'indice cluster sono permanentemente indipendenti nelle pagine dell'indice), questo è un trucco (work-arounndnd) che consente di ottenere DUE indici raggruppati su una tabella.
Charles Bretana,

51

In generale, no. Le viste sono utilizzate principalmente per comodità e sicurezza e non produrranno (da sole) alcun vantaggio in termini di velocità.

Detto questo, SQL Server 2000 e versioni successive dispongono di una funzionalità denominata Visualizzazioni indicizzate che può migliorare notevolmente le prestazioni, con alcune avvertenze:

  1. Non tutte le viste possono essere trasformate in una vista indicizzata; devono seguire un insieme specifico di linee guida , che (tra le altre restrizioni) mezzo che non è possibile includere elementi di query comuni come COUNT, MIN, MAX, o TOP.
  2. Le viste indicizzate utilizzano lo spazio fisico nel database, proprio come gli indici su una tabella.

Questo articolo descrive ulteriori vantaggi e limitazioni delle viste indicizzate :

Puoi…

  • La definizione della vista può fare riferimento a una o più tabelle nello stesso database.
  • Una volta creato l'indice cluster univoco, è possibile creare altri indici non cluster sulla vista.
  • È possibile aggiornare i dati nelle tabelle sottostanti, inclusi inserimenti, aggiornamenti, eliminazioni e persino tronchi.

Non puoi ...

  • La definizione della vista non può fare riferimento ad altre viste o tabelle in altri database.
  • Non può contenere COUNT, MIN, MAX, TOP, join esterni o poche altre parole chiave o elementi.
  • Non è possibile modificare le tabelle e le colonne sottostanti. La vista viene creata con l'opzione WITH SCHEMABINDING.
  • Non è sempre possibile prevedere cosa farà lo Strumento per ottimizzare le query. Se si utilizza Enterprise Edition, considererà automaticamente l'indice cluster univoco come un'opzione per una query, ma se trova un indice "migliore", verrà utilizzato. È possibile forzare l'ottimizzatore a utilizzare l'indice tramite il suggerimento WITH NOEXPAND, ma prestare attenzione quando si utilizza qualsiasi suggerimento.

3
totalmente in disaccordo ... la lettura da una vista consente di riscrivere l'SQL .. ed è generalmente PIÙ VELOCE da leggere da una vista (piuttosto che da un dump della vista).
Aaron Kempf,

@AaronKempf, mi piacerebbe vedere qualche riferimento a riguardo, che non è stata la mia esperienza. Quando cerco "visualizza SQL riscritto", tutti i risultati che ottengo fanno riferimento a Oracle, non a SQL Server, ad esempio docs.oracle.com/cd/E14072_01/server.112/e10810/qrbasic.htm
BradC

Ieri stavo facendo alcuni benchmark su di esso, sono rimasto sbalordito .. fondamentalmente se prendo un dump da una vista (in una tabella) qualsiasi query che eseguo è SLOWER .. perché la maggior parte delle query passa attraverso la vista come burro e viene riscritta dal Query Optimizer .. Almeno questo è quello che presumo. Proverò presto a scrivere un post sul blog, il benchmarking è stato roba abbastanza affascinante .. Fondamentalmente le visualizzazioni aiutano enormemente le prestazioni.
Aaron Kempf,

@AaronKempf Non sono sicuro che sia anche lo stesso scenario della domanda originale (che riguarda una query rispetto a mettere quella query identica in una vista). Ad ogni modo, non riesco a vedere come materializzare una vista in una tabella la renderebbe PIÙ LENTA (è esattamente ciò che fa una vista indicizzata), a meno che la tua nuova tabella non abbia buoni indici.
BradC,

1
Brad; Ho scritto un post sul blog davvero pessimo su come le visualizzazioni mi stiano risparmiando il 99% delle mie prestazioni in questa situazione .. Sto programmando di scrivere un paio di altri articoli, ma so che devo aggiungere un mucchio di dettagli in più. Ti dispiace dare un'occhiata a questo e dirmi cosa ne pensi della mia descrizione? So che non avrà più senso (fino a quando non avrò 2-3 altri articoli) .. ma sono follemente innamorato delle viste e lo sono da molto tempo! accessadp.com/2013/01/22/do-views-increase-performance
Aaron Kempf

14

Almeno in SQL Server, i piani di query sono archiviati nella cache dei piani sia per le viste che per le normali query SQL, in base ai parametri query / vista. Per entrambi, vengono eliminati dalla cache quando non vengono utilizzati per un periodo sufficientemente lungo e lo spazio è necessario per qualche altra query appena inviata. Dopodiché, se viene emessa la stessa query, viene ricompilata e il piano viene reinserito nella cache. Quindi no, non c'è alcuna differenza, dato che stai riutilizzando la stessa query SQL e la stessa vista con la stessa frequenza.

Ovviamente, in generale, una vista, per sua stessa natura (che qualcuno pensava che dovesse essere usata abbastanza spesso per trasformarla in una vista) è generalmente più probabile che venga "riutilizzata" rispetto a qualsiasi istruzione SQL arbitraria.


14

EDIT: ho sbagliato e dovresti vedere Marks rispondere sopra.

Non posso parlare per esperienza con SQL Server , ma per la maggior parte dei database la risposta sarebbe no. L'unico potenziale vantaggio che si ottiene, dal punto di vista delle prestazioni, dall'uso di una vista è che potrebbe potenzialmente creare alcuni percorsi di accesso basati sulla query. Ma il motivo principale per utilizzare una vista è semplificare una query o standardizzare un modo di accedere ad alcuni dati in una tabella. In generale, non otterrai un vantaggio in termini di prestazioni. Potrei sbagliarmi, però.

Vorrei presentare un esempio moderatamente più complicato e fare in modo che tu stesso lo veda.


1
un altro motivo per le visualizzazioni è di aiutare il controllo degli accessi nei modelli basati sui ruoli
annakata,

1
Ti sbagli sui miglioramenti delle prestazioni. Non ho spiegato abbastanza per convincere alcune persone nel mio commento originale, ma MS ha una documentazione esplicita su come utilizzare le visualizzazioni per migliorare le prestazioni. Vedi la mia risposta (ora fortemente sottovalutata) di seguito.
Mark Brittingham,

7

Potrebbe essere più veloce se si crea una vista materializzata ( con associazione dello schema ). Le viste non materializzate vengono eseguite esattamente come la query normale.


schemabinding ha poco a che fare con le prestazioni, lega lo schema della vista alla tabella sottostante, quindi rimane sincronizzato ed è un pre-req per le viste indicizzate.
Sam Saffron,

5

La mia comprensione è che un po 'di tempo fa, una vista sarebbe più veloce perché SQL Server poteva archiviare un piano di esecuzione e quindi utilizzarlo invece di provare a capirne uno al volo. Penso che i guadagni delle prestazioni al giorno d'oggi non siano probabilmente così grandi come una volta, ma dovrei indovinare che ci sarebbe qualche miglioramento marginale per usare la vista.


Questa era la mia comprensione: un tempo contava, non più
annakata,

Non dal punto di vista delle prestazioni, lo fa come mezzo per limitare l'accesso. Ma questo sarebbe un altro argomento. ;)
AnonJr

oh certo, molte buone ragioni per usare le viste, non una sola per usare query non
elaborate

4

Sicuramente una vista è migliore di una query nidificata per SQL Server. Senza sapere esattamente perché sia ​​meglio (fino a quando non ho letto il post di Mark Brittingham), avevo eseguito alcuni test e sperimentato miglioramenti delle prestazioni quasi scioccanti quando utilizzavo una vista rispetto a una query nidificata. Dopo aver eseguito ciascuna versione della query diverse centinaia di volte di seguito, la versione di visualizzazione della query è stata completata in metà tempo. Direi che è abbastanza prova per me.


Grazie Giordania ... felice di sapere che tutta questa teoria funziona nel mondo reale .
Mark Brittingham,

ho esperienza con la vista nidificata (vista in vista) e le prestazioni sono state pessime. Quando tutte le viste sono state riscritte in sotto-selezioni, le prestazioni sono state molte volte più veloci, quindi forse c'è posto per alcuni test seri.
Muflix,

2

Mi aspetto che le due query funzionino in modo identico. Una vista non è altro che una definizione di query memorizzata, non esiste memorizzazione nella cache o memorizzazione dei dati per una vista. L'ottimizzatore trasformerà efficacemente la tua prima query nella seconda query quando la eseguirai.


Se la vista è un piccolo insieme di campi e quei campi sono coperti da un indice, SQL Server è abbastanza intelligente da utilizzare quell'indice di copertura quando soddisfa la seconda forma di query?
AnthonyWJones,

1

Tutto dipende dalla situazione. Le viste indicizzate MS SQL sono più veloci di una vista o query normale ma le viste indicizzate non possono essere utilizzate in un invironment di database speculare (MS SQL).

Una vista in qualsiasi tipo di ciclo provocherà un serio rallentamento perché la vista viene ripopolata ogni volta che viene chiamata nel ciclo. Come una query. In questa situazione, una tabella temporanea che utilizza # o @ per conservare i dati per eseguire il ciclo è più veloce di una vista o di una query.

Quindi tutto dipende dalla situazione.


0

Non ci sono differenze pratiche e se leggi BOL scoprirai che mai il tuo semplice SQL SELECT * FROM X sfrutta la cache del piano, ecc.


0

Dovrebbe esserci un vantaggio insignificante nell'archiviazione del piano di esecuzione, ma sarà trascurabile.


0

Lo scopo di una vista è utilizzare la query più e più volte. A tal fine, SQL Server, Oracle, ecc. In genere forniscono una versione "memorizzata nella cache" o "compilata" della vista, migliorandone così le prestazioni. In generale, ciò dovrebbe comportarsi meglio di una query "semplice", sebbene se la query è veramente molto semplice, i vantaggi potrebbero essere trascurabili.

Ora, se stai eseguendo una query complessa, crea la vista.


0

Secondo me, l'uso della vista è un po 'più veloce di una normale query. La mia procedura memorizzata impiegava circa 25 minuti (lavorando con set di record più grandi e join multipli) e dopo aver usato la vista (non cluster), le prestazioni erano solo un po 'più veloci ma per nulla significative. Ho dovuto usare alcune altre tecniche / metodi di ottimizzazione delle query per renderlo un cambiamento drammatico.


Il modo in cui stiamo scrivendo / progettando la query è molto importante.
kta,

Ho scoperto che usare i CTE per limitare i dati che ritornano da una tabella e quindi fare tutto il lavoro / i join, ecc. Al di fuori dei CTE ha migliorato notevolmente le prestazioni in molti casi
MattE

0

Selezionare da una vista o da una tabella non avrà molto senso.

Naturalmente se la vista non ha join, campi, ecc. Non necessari, è possibile controllare il piano di esecuzione delle query, dei join e degli indici utilizzati per migliorare le prestazioni della vista.

Puoi persino creare un indice nelle viste per requisiti di ricerca più rapidi. http://technet.microsoft.com/en-us/library/cc917715.aspx

Ma se stai cercando '% ...%' rispetto al motore sql non trarrà beneficio da un indice sulla colonna di testo. Se riesci a forzare i tuoi utenti a effettuare ricerche come '...%' di quello sarà veloce

riferito alla risposta sui forum asp: https://forums.asp.net/t/1697933.aspx?Which+is+faster+when+using+SELECT+query+VIEW+or+Table+


0

Contro ogni aspettativa, le viste sono molto più lente in alcune circostanze.

L'ho scoperto di recente quando ho avuto problemi con i dati estratti da Oracle che dovevano essere massaggiati in un altro formato. Forse 20k righe di origine. Un tavolino. Per fare ciò abbiamo importato i dati dell'oracolo il più possibile invariato in una tabella e quindi abbiamo utilizzato le viste per estrarre i dati. Abbiamo avuto viste secondarie basate su quelle viste. Forse 3-4 livelli di visualizzazioni.

Una delle query finali, che ha estratto forse 200 righe, richiederebbe 45 minuti in più! Quella query si basava su una cascata di visualizzazioni. Forse 3-4 livelli di profondità.

Potrei prendere ciascuna delle viste in questione, inserire il suo sql in una query nidificata ed eseguirlo in un paio di secondi.

Abbiamo anche scoperto che potevamo anche scrivere ogni vista in una tabella temporanea e interrogarla al posto della vista ed era ancora molto più veloce del semplice utilizzo delle viste nidificate.

Ciò che è stato ancora più strano è che le prestazioni sono andate bene fino a quando non abbiamo raggiunto il limite delle righe di origine che sono state inserite nel database, le prestazioni sono state semplicemente eliminate da un paio di giorni nello spazio: sono bastate poche righe di origine.

Quindi, usare query che estraggono da viste che estraggono da viste è molto più lento di una query nidificata, il che non ha senso per me.


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.