Vista indicizzata in SQL Server


11

Ho una tabella e una vista indicizzata su di esso come

Create table mytable1 (ID int identity(1,1), Name nvarchar(100))

Create table mytable2 (ID int identity(1,1), Name nvarchar(100))

Create view myview 
with schemabinding 
as 
   select a.name, b.name
   from mytable1 a 
   join mytable2 b on a.Id = b.Id

Ora se eseguo la seguente query

select a.name, b.name
from mytable1 a 
join mytable2 b on a.Id = b.Id

Non usa la mia vista indicizzata. C'è qualche suggerimento (o altro) per forzare invece SQL Server a utilizzare la vista indicizzata?

Ho un grande sistema e devo ottimizzarlo. Non posso modificare tutti i miei script SQL per selezionare dalla vista anziché dalle tabelle. Voglio creare viste indicizzate e forzare SQL Server a ottenere dati da loro anziché dalle tabelle.

Sto usando SQL Server 2014 Enterprise Edition.


Ho un grande sistema e devo ottimizzarlo. Non posso cambiare tutti i miei script sql per selezionare dalla vista anziché dalle tabelle. Voglio creare viste indicizzate e forzare il server sql a ottenere dati da loro anziché tabelle.
Artashes Khachatryan,

Risposte:


23

Costruisco continuamente visualizzazioni indicizzate in SQL Server per ottimizzare i prodotti esistenti. L'ottimizzatore è abbastanza intelligente da utilizzare l'indice se si utilizzano le colonne appropriate.

Usando il tuo esempio, sembra che tu abbia creato la vista ma in realtà non abbia creato un indice su di essa.

if object_id(N'mytable1') is not null 
drop table mytable1
if object_id(N'mytable2') is not null 
drop table mytable2
go

Create table mytable1 (ID int identity(1,1), Name1 nvarchar(100))
GO
Create table mytable2 (ID int identity(1,1), Name2 nvarchar(100))
GO

insert into mytable1 values ('steve')
insert into mytable1 values ('jack') 
insert into mytable1 values ('mike') 
insert into mytable1 values ('ralph') 
insert into mytable1 values ('simon')

insert into mytable2 values ('smith')
insert into mytable2 values ('jackson') 
insert into mytable2 values ('mikaelson') 
insert into mytable2 values ('montalvo') 
insert into mytable2 values ('singer')
go

if object_id(N'myview') is not null
drop view myview
go

Create view myview 
with schemabinding 
as 
select a.id, a.name1, b.name2
from dbo.mytable1 a 
join dbo.mytable2 b on a.Id = b.Id
GO

select a.name1, b.name2
from mytable1 a join mytable2 b on a.Id = b.Id
GO

Poiché non esiste alcun indice in questa vista, eseguiamo la scansione delle tabelle di base: inserisci qui la descrizione dell'immagine

Ma una volta aggiunto un indice, l'ottimizzatore può utilizzarlo:

CREATE UNIQUE CLUSTERED INDEX [ix_cl_names] ON [myview]
(
    [name1] ASC,
    [name2] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

Questo ha usato la vista in modo appropriato: inserisci qui la descrizione dell'immagine

Non posso modificare tutti i miei script SQL per selezionare dalla vista anziché dalle tabelle. Voglio creare viste indicizzate e forzare SQL Server a ottenere dati da loro anziché dalle tabelle.

Non esiste alcun suggerimento o altro metodo per forzare SQL Server a utilizzare una vista indicizzata quando non viene indicato nella query.

Ulteriori informazioni (da Geoff Patterson )

Un altro punto è che mentre l'ottimizzatore può, solo in Enterprise Edition, utilizzare la vista indicizzata in questo caso, può avere senso fare riferimento direttamente alla vista usando il NOEXPANDsuggerimento se devi essere sicuro al 100% dell'indice della vista in uso o se mai vuoi che sia usato in Standard Edition.

Ho visto spesso query anche in Enterprise Edition in cui l'ottimizzatore non rileva il fatto che l'indice di visualizzazione può essere utilizzato a meno che non NOEXPANDvenga utilizzato. È più comune con query complesse, ma può accadere anche con query semplici.

Paul White ha uno dei migliori articoli che ho letto esplorando le sfumature di NOEXPAND; oltre al semplice utilizzo dell'indice della vista, il suggerimento può anche influire su cose come la creazione automatica di statistiche sulla vista indicizzata e le stime di cardinalità per il piano.

E da Zane : come nota a margine, fai attenzione alle viste indicizzate come qualsiasi altro indice che aggiungerà ai tuoi tempi di aggiornamento, inserimento ed eliminazione.


-5

Se non è possibile modificare il codice dell'applicazione in nuovi nomi di oggetto, forse è possibile modificare l'utente dell'applicazione per utilizzare un nuovo schema predefinito e creare le viste indicizzate in un altro schema utilizzando gli stessi nomi oggetto? Per esempio:

create view iv.MyTest 
as 
 select Col1, Col2 from dbo.MyTest 

Ovviamente questo funzionerà solo se non hai usato i nomi degli schemi nel codice dell'applicazione.

In tal caso, è possibile provare a spostare tutti gli oggetti in un nuovo schema e introdurre invece le viste nel vecchio schema.

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.