2012-04-06 12 views
21

Utilizzo MSSQL Server 2008 R2 e sto cercando di ottimizzare le mie visualizzazioni quando mi sono imbattuto in visualizzazioni indicizzate. Sfortunatamente la maggior parte delle mie visualizzazioni usa un Left Outer Joins che non è supportato con le viste indicizzate. Dopo una serie di ricerche, sono rimasto confuso nel modo migliore per farlo. Il mio modo di vedere, ho le seguenti opzioni:Visualizzazioni indicizzate e join di sinistra una volta per tutte

1) convertire la sinistra si unisce al inner join usando il trucco per simulare una sinistra unirsi a "O (IsNull (a) e IsNull (b))"

Ho trovato questa soluzione in un paio di posti, ma si è parlato di una perdita di prestazioni.

2) Convertire fianco join a join interni e sostituire nulli della colonna Null con guids vuoti (00000000-0000-0000-0000-000000000000) e aggiungere una singola riga nella tabella di destra con un GUID corrispondente.

Questo sembra il più ovvio per quanto riguarda le prestazioni, ma sembra uno spreco di spazio per ogni riga che altrimenti sarebbe NULL.

3) Rompere la vista in due viste. La prima vista è la maggior parte della mia logica che è indicizzabile. E la seconda vista deriva dalla prima vista e l'aggiunta dei join di sinistra.

L'idea è che ci potrebbe essere un aumento delle prestazioni tramite la vista di base che viene indicizzata. E che anche l'interrogazione della vista derivata otterrebbe almeno alcuni dei benefici in termini di prestazioni.

4) Non indicizzare le mie opinioni

Would lasciando la vista il senso che è essere più performante rispetto a qualsiasi delle opzioni di cui sopra?

5) L'idea non pensavo di

ho sceneggiato il mio scenario di base come segue:

CREATE TABLE [dbo].[tbl_Thumbnails](
     [ThumbnailId] [uniqueidentifier] NOT NULL, 
     [Data] [image] NULL, 
     [Width] [smallint] NOT NULL, 
     [Height] [smallint] NOT NULL 
    CONSTRAINT [PK_tbl_Thumbnails] PRIMARY KEY CLUSTERED 
    (
     [ThumbnailId] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

    GO 

    CREATE TABLE [dbo].[tbl_Tags](
     [TagId] [uniqueidentifier] NOT NULL, 
     [ThumbnailId] [uniqueidentifier] NULL 
    CONSTRAINT [PK_tbl_Tags] PRIMARY KEY CLUSTERED 
    (
     [TagId] ASC 
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ) ON [PRIMARY] 

    GO 

    CREATE VIEW [dbo].[v_Tags] WITH SCHEMABINDING AS 
    SELECT  dbo.tbl_Tags.TagId, dbo.tbl_Tags.ThumbnailId 
    FROM   dbo.tbl_Tags LEFT OUTER JOIN 
          dbo.tbl_Thumbnails 
    ON  dbo.tbl_Tags.ThumbnailId = dbo.tbl_Thumbnails.ThumbnailId 

    GO 

    INSERT INTO tbl_Tags VALUES ('16b23bb8-bf17-4784-b80a-220da1163584', NULL) 
    INSERT INTO tbl_Tags VALUES ('e8b50f03-65a9-4d1e-b3b4-268f01645c4e', 'a45e357b-ca9c-449a-aa27-834614eb3f6e') 
    INSERT INTO tbl_Thumbnails VALUES ('a45e357b-ca9c-449a-aa27-834614eb3f6e', NULL, 150, 150) 

Ora, facendo le seguenti rese di query "Impossibile creare l'indice sulla vista" Test .dbo.v_Tags "perché utilizza una SINISTRA, DESTRA, o full outer join, e nessun outer join sono ammessi in viste indicizzate considerare l'utilizzo di un INNER join, invece.":

CREATE UNIQUE CLUSTERED INDEX [TagId] ON [dbo].[v_Tags] 
(
[TagId] ASC 
) 
GO 

Questo è il comportamento previsto, ma quale linea di condotta consiglieresti per ottenere le migliori prestazioni dal mio scenario? Il punto di partenza qui è la migliore prestazione.

+1

Che cosa si finisce per fare con questo? Sto affrontando un problema simile cercando di indicizzare alcune visualizzazioni. – user1948635

+0

Affrontare situazioni simili, la tabella denormalizzata (con trigger o qualche altro modo di tenerla aggiornata) potrebbe essere un'opzione nella lista. –

+0

Ho risposto a una domanda molto simile sulla materializzazione degli indici sui join di sinistra. Mentre non c'è un modo diretto per farlo ... ecco l'opzione # 5 http://stackoverflow.com/a/31171129/1902664 – cocogorilla

risposta

6

Perché stai indicizzando le tue visualizzazioni? Hai menzionato "spreco di spazio" nella tua soluzione 2, ma lo sapevi che quando indicizzi la tua vista, la conservi sul DB?

In altre parole, si effettua una copia dei dati che la vista restituisce sul DB e ogni volta che i dati vengono aggiornati sulle tabelle di origine, alcuni meccanismi interni di SQL Server devono aggiornarlo su questa nuova struttura dati creata perché ora il server SQL legge dalla vista, non i tavoli più.

Se si utilizza Profiler + DTA o addirittura DMVS si può trovare con gli indici corretti da creare sulle vostre tavole che qualsiasi vista trarrebbe beneficio da

+1

Cosa succede se la vista presenta dati quasi costanti (raramente modificati nelle tabelle sottostanti) ed è usato anche in molti posti? In questo caso, la vista indicizzata aiuta molto per le prestazioni in questo caso – Thetam

+0

, sì. Hai ragione – Diego

+2

Devi anche indicizzare la tua vista se vuoi creare un indice di testo completo su di esso. –

Problemi correlati