SQL Server ed ALM su database


Il blog di Alessandro Alpi
Archivio Posts
Anno 2018

Anno 2017

Anno 2016

Anno 2015

Anno 2014

Anno 2013

Anno 2012

Anno 2011

Anno 2010

Anno 2009

Anno 2008

Anno 2007

Anno 2006

SQL Server 2008 Management Studio - Filtered index perso in generazione script

Per chi possiede SQL Server 2008 (non ho testato su R2), e quindi per chi può usufruire dei filtered index, volevo sottolineare questo problema:

SCENARIO
Immaginiamo di avere una tabella così fatta:

USE tempdb;

GO

 

CREATE TABLE dbo.FooData

(

         IDFooData int IDENTITY(1, 1) NOT NULL PRIMARY KEY

       , FooData varchar(20) NOT NULL

       , FooTime datetime NOT NULL

);

 

INSERT INTO dbo.FooData (FooData, FooTime)

VALUES

         ('UNO', '20111018 15:00')

       , ('DUE', '20111018 16:00')

       , ('TRE', '20111018 17:00')

       , ('QUATTRO', '20111018 18:00')

       , ('CINQUE', '20111018 19:00')

       , ('SEI', '20111018 20:00')

       , ('SETTE', '20111018 21:00')

GO

 

Immaginiamo ora di creare un indice su questa tabella, filtrato in questo modo:

CREATE NONCLUSTERED INDEX IX_dboFooData_FilterFooTime ON dbo.FooData (FooData ASC)

WHERE (FooTime>='20111018 17:00')

GO


Questo indice è ridotto ad una porzione di tabella, ed è quindi ottimizzato solo per quell'area di dati. Può essere ovviamente solo nonclustered.

Ora, immaginiamo di non voler utilizzare il codice andando ad aggiungere un campo all'indice tramite designer di tabella (sconsiglio sempre l'utilizzo dei designer, ma a volte sono molto comodi). 
Abbiamo aggiunto temporaneamente le colonne all'indice. Attenzione però, prima di salvare, generate il Change Script, premendo il tasto apposito sulla sulla testata. Avremo quanto segue:

/* To prevent any potential data loss issues, you should review this script 

in detail before running it outside the context of the 

database designer.*/

BEGIN TRANSACTION

SET QUOTED_IDENTIFIER ON

SET ARITHABORT ON

SET NUMERIC_ROUNDABORT OFF

SET CONCAT_NULL_YIELDS_NULL ON

SET ANSI_NULLS ON

SET ANSI_PADDING ON

SET ANSI_WARNINGS ON

COMMIT

BEGIN TRANSACTION

GO

DROP INDEX IX_dboFooData_FilterFooTime ON dbo.FooData

GO

CREATE NONCLUSTERED INDEX IX_dboFooData_FilterFooTime ON dbo.FooData

       (

       FooData,

       IDFooData

       ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 

       ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

GO

ALTER TABLE dbo.FooData SET (LOCK_ESCALATION = TABLE)

GO

COMMIT


Il filtro non c'è. Ciò succede perchè nel designer non è possibile mettere da nessuna parte il predicato del filtered index e quindi il filtro è visto come una differenza da rimuovere (c'era prima e non c'è ora, ovvero si vuole togliere ), si tratta di un changeset errato. Il mio consiglio è quindi quello di controllare SEMPRE il change script prima di committare, perchè se confermate salvando quanto vi genera il designer, in questo caso, otterrete un indice diverso da quello che vi aspettate:

USE [tempdb]

GO

 

/****** Object:  Index [IX_dboFooData_FilterFooTime]    Script Date: 10/18/2011 19:15:14 ******/

CREATE NONCLUSTERED INDEX [IX_dboFooData_FilterFooTime] ON [dbo].[FooData]

(

       [FooData] ASC,

       [IDFooData] 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

 

 

Dov'è il filtro? 


Riferimenti:
Per maggiori info sui filtered index, clickare su questo link.

Stay tuned! 


Categoria: SQL Server 2008
martedì, 11 ott 2011 Ore. 00.09

Messaggi collegati


Statistiche
  • Views Home Page: 479.476
  • Views Posts: 864.982
  • Views Gallerie: 498.875
  • n° Posts: 484
  • n° Commenti: 273



















Copyright © 2002-2007 - Blogs 2.0
dotNetHell.it | Home Page Blogs
ASP.NET 2.0 Windows 2003