Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Indice ripristinabile di SQL Server:va bene per te?

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.