SQL 2017 ha introdotto la possibilità di sospendere e riprendere le operazioni di ricostruzione dell'indice durante la manutenzione del database. Questa funzione offre maggiore flessibilità agli amministratori di database in quanto consente loro di scegliere tra la reindicizzazione offline e online oltre a sospendere e riprendere la ricostruzione dell'indice quando necessario.
Prima del rilascio dell'indice ripristinabile, gli amministratori del database potevano eseguire la ricostruzione dell'indice offline e online .
Offline offre un'esecuzione più rapida, poiché la tabella è bloccata per qualsiasi lettura oppure scrivi operazione e il nuovo indice viene creato dal vecchio indice. Durante questo processo, non è consentita alcuna operazione di lettura o scrittura. Al termine dell'operazione, il blocco della tabella viene rilasciato e le operazioni di lettura e scrittura sono nuovamente consentite. Offline l'opzione è naturalmente più veloce.
Online mantiene la tabella aperta per la lettura e scrivi operazioni. È stata creata un'altra copia dell'indice e tutte le operazioni di ricostruzione dell'indice si trovano in quella copia. Tutte le nuove operazioni sulle righe vengono scritte in entrambi gli indici. Al termine della ricostruzione, il passaggio è terminato e la nuova copia dell'indice viene utilizzata. Il Online ricostruzione consente operazioni di ricostruzione mentre il database è in linea. I tempi di fermo sono minimi.
Si noti che la funzionalità dell'indice ripristinabile è disponibile solo nell'edizione SQL Server Enterprise e nell'edizione gratuita per sviluppatori. Se hai questa opzione sul tavolo, puoi giocarci, fare un semplice test e vedere se questa funzione è utile nel tuo caso.
La documentazione Microsoft indica i seguenti aspetti per le tue considerazioni:
- Puoi gestire, pianificare ed estendere le finestre di manutenzione dell'indice. Puoi mettere in pausa e riavviare le operazioni di creazione o ricostruzione dell'indice quando è necessario adattare le finestre di manutenzione.
- Puoi eseguire il ripristino dall'indice per creare o ricostruire errori (come failover del database o esaurimento dello spazio su disco).
- Fai attenzione che quando un'operazione sull'indice viene sospesa, sia l'indice originale che quello appena creato richiedono spazio su disco. Dovrai aggiornarli durante le operazioni DML.
- Puoi abilitare il troncamento dei log delle transazioni durante le operazioni di creazione o ricostruzione dell'indice.
- Nota che l'opzione SORT_IN_TEMPDB=ON non è supportata
Testiamo la ricostruzione dell'indice ripristinabile. Userò un'immagine del contenitore che esegue l'edizione SQL 2019 Server Developer. Inoltre, creerò una piccola tabella con solo un paio di colonne e inserirò circa un milione di righe in quella tabella. Puoi ingrandire la tabella con più righe.
Poiché sto usando una macchina Linux e non posso installare SQL Server Management Studio, userò il client Azure Data Studio per connettermi al mio SQL Server. Dai un'occhiata allo screenshot delle mie proprietà di SQL Server:
Creeremo un database di esempio, una tabella e un indice con gli script T-SQL seguenti. Puoi eseguirli perfettamente con SSMS o dbForge Studio per SQL Server:
-- Create a new database called 'DatabaseName'
-- Connect to the 'master' database to run this snippet
USE master
GO
-- Create the new database if it does not exist already
IF NOT EXISTS (
SELECT [name]
FROM sys.databases
WHERE [name] = N'dbatools'
)
CREATE DATABASE dbatools
GO
Use dbatools
-- Create a new table called '[TableName]' in schema '[dbo]'
-- Drop the table if it already exists
IF OBJECT_ID('[dbo].[TabletoIndex]', 'U') IS NOT NULL
DROP TABLE [dbo].[TabletoIndex]
GO
-- Create the table in the specified schema
CREATE TABLE [dbo].[TabletoIndex]
(
[Id] INT NOT NULL PRIMARY KEY, -- Primary Key column
[ColumnName1] NVARCHAR(50) NOT NULL
-- Specify more columns here
);
GO
Per popolare la tabella con dati casuali, eseguire lo script seguente:
--populate the table
SET NOCOUNT ON
Declare @Id int
Set @Id = 1
While @Id <= 1000000
Begin
Insert Into TabletoIndex values (@Id, 'Name - ' + CAST(@Id as nvarchar(10))) Set @Id = @Id + 1
End
SELECT count(*) from TabletoIndex
Con una tabella popolata pronta, possiamo procedere all'indice ripristinabile. Iniziamo con la creazione di quell'indice:
-- Create a nonclustered index with or without a unique constraint -- Or create a clustered index on table '[TableName]' in schema '[dbo]' in database '[DatabaseName]'
CREATE UNIQUE INDEX IX_ID_Name ON [dbo].[TabletoIndex] (ID desc, [ColumnName1] DESC) WITH (SORT_IN_TEMPDB = OFF, RESUMABLE=ON, ONLINE = ON, MAX_DURATION=1) GO
Notare nuove opzioni/parametri nel comando precedente. RESUMABLE=ON significa che vogliamo avere un'operazione di indice ripristinabile. Durata_massima è il valore in minuti che definisce per quanto tempo vogliamo che venga eseguita l'indicizzazione.
Mentre il comando precedente è in esecuzione, apri un'altra sessione ed esegui il comando T-SQL seguente per PAUSA l'attività di ricostruzione in corso:
--Rebuild WITH RESUMABLE functionality
ALTER INDEX IX_ID_Name ON [dbo].[TabletoIndex] PAUSE
GO
Se la PAUSA comando è riuscito, sospendiamo l'operazione di indicizzazione in corso iniziata circa un minuto fa. Tuttavia, quando torni alla sessione precedente per il comando di ricostruzione con resumable=ON , restituisce un brutto errore. Uffa. Ma sì, questo è il comportamento previsto.
Con questa ricostruzione dell'indice ripristinabile, SQL Server ha anche introdotto un nuovo sys.index_resumable_operations DMV per controllare le operazioni sospese. Proviamo a esaminare questo DMV:
La query del risultato DMV restituisce il mio comando di ricostruzione dell'indice, la percentuale di completamento è un'ottima cosa e altro ancora. Al termine di tutte le operazioni di ricostruzione dell'indice, DMV restituisce vuoto:
Abbastanza carino, eh?
E se cambiassi idea sul tavolo? E se si verificasse una modifica dei requisiti e fosse necessario apportare modifiche alla progettazione del database? Proviamo ad abbandonare il tavolo:
Fornirà un altro brutto e lungo messaggio di errore:
Msg 10637, livello 16, stato 1, riga 1
Impossibile eseguire questa operazione su "oggetto" con ID 581577110 poiché uno o più indici sono attualmente in stato di ricostruzione dell'indice ripristinabile. Fare riferimento a sys.index_resumable_operations per maggiori dettagli.
Tempo totale di esecuzione:00:00:00.018
Da qui, ti renderai conto che non hai altra scelta che ANNULLARE completamente l'operazione o RIPRENDERE e lasciare che la ricostruzione venga completata.
Vedere il comando T-SQL per riprendere o interrompere l'operazione. Quindi puoi eliminare la tabella con successo:
ALTER INDEX IX_ID_Name ON [dbo].[TabletoIndex] RESUME
ALTER INDEX IX_ID_Name ON [dbo].[TabletoIndex] ABORT
Lo stesso errore si verificherà anche se devi eseguire altre operazioni come eliminare completamente l'indice o terminare la sessione corrente.
Ma ti chiedi, è l'opzione ripristinabile in primo luogo? La risposta è no. Per SQL 2019, tutta la creazione di indici avviene con RESUMABLE=ON per impostazione predefinita. È a causa di queste 2 dichiarazioni di scopo:
ALTER DATABASE SCOPED CONFIGURATION SET ELEVATE_ONLINE=WHEN_SUPPORTED ALTER DATABASE SCOPED CONFIGURATION SET ELEVATE_RESUMABLE=WHEN_SUPPORTED
Riepilogo
L'impatto dell'utilizzo dell'opzione ripristinabile sulle prestazioni non è diverso dall'utilizzo della normale operazione di reindicizzazione. SQL Server ti offre solo un maggiore controllo sulle operazioni di manutenzione del database.
Per quanto riguarda i requisiti di ricostruzione dell'indice della tavola periodica, la best practice continua a eseguire le operazioni sull'indice offline, o almeno durante le ore non di punta per garantire un impatto minimo sul business.