2012-07-02 5 views
5

Sto lavorando per fornire un metodo per consentire l'aggiornamento in blocco delle nostre tabelle (più di 1 milione di righe nuove o aggiornate per aggiornamento) ed era interessato a eliminare gli indici correnti e ricrearli dopo gli aggiornamenti.Rilascia e recupera automaticamente gli indici correnti

Mi chiedevo se qualcuno ha uno script per fornire un accoppiamento lento di queste operazioni in modo che se gli indici cambiano nel tempo, il processo di aggiornamento non cambia.

Sembra che questa sia una di quelle cose che la comunità ha già probabilmente risolto.

+2

Specificare l'RDBMS a cui si sta mirando aggiungendo il tag appropriato (Oracle, SQL Server, MySQL ecc.). Ci saranno risposte che sfruttano il linguaggio o le caratteristiche del prodotto che non sono universalmente supportate. Inoltre, taggandolo con un RDBMS specifico, la tua domanda potrebbe ricevere l'attenzione di persone più adatte a rispondere alla tua domanda. – Ben

risposta

10

Ho uno script che utilizzo per interrogare le tabelle di sistema per acquisire tutti gli indici non in cluster e disabilitare la ricostruzione al termine. Il seguente è per l'uso su edizione standard, se si è in azienda vorrei aggiungere l'opzione ONLINE.

Disabilita

DECLARE @sql AS VARCHAR(MAX); 
SET @sql = ''; 
SELECT 
    @sql = @sql + 'ALTER INDEX [' + i.name + '] ON [' + o.name + '] DISABLE; ' 
FROM sys.indexes AS i 
JOIN sys.objects AS o ON i.object_id = o.object_id 
WHERE i.type_desc = 'NONCLUSTERED' 
AND o.type_desc = 'USER_TABLE' 

EXEC (@sql) 

Ricostruire

DECLARE @sql AS VARCHAR(MAX); 
SET @sql = ''; 
SELECT 
    @sql = @sql + 'ALTER INDEX [' + i.name + '] ON [' + o.name + '] REBUILD WITH (FILLFACTOR = 80); ' 
FROM sys.indexes AS i 
JOIN sys.objects AS o ON i.object_id = o.object_id 
WHERE i.type_desc = 'NONCLUSTERED' 
AND o.type_desc = 'USER_TABLE' 

EXEC (@sql); 

Mi piace questo metodo in quanto è molto personalizzabile, come è possibile escludere/includere alcune tabelle in base alle condizioni, così come evitare una cursore. Inoltre è possibile modificare EXEC in PRINT e vedere il codice che verrà eseguito manualmente.

Condizioni di escludere un tavolo

AND o.name NOT IN ('tblTest','tblTest1'); 
+1

Fantastico! semplicemente invertendo il Not IN. Molto più facile del drop e creare cosa stavo cercando di fare –

+1

Puoi anche usare 'sys.tables' invece di' sys.objects' e salvarti per specificare 'WHERE o.type_desc = 'USER_TABLE'' tutto il tempo .... –

4
EXEC sp_MSforEachTable 'ALTER INDEX ALL ON ? DISABLE' 

e

EXEC sp_MSforEachTable 'ALTER INDEX ALL ON ? REBUILD' 

è tutto ciò che serve se si vuole farlo per tutte le tabelle e ogni indice.

+0

Ho riscontrato un problema. Tabelle con disabilitato L'indice cluster non può contenere alcuna riga inserita, poiché la tabella diventa disabilitata. – Stoleg

+0

Si prega di chiedere questa come una domanda autonoma. C'è troppo poco spazio ... – fancyPants

+0

'INSERT INTO' non riesce su una tabella con indice cluster disabilitato. Le righe di dati in una tabella con indice cluster disabilitato sono disponibili solo per le operazioni di eliminazione o di ricostruzione. – Stoleg