O SQL 2017 introduziu a capacidade de pausar e retomar as operações de reconstrução de índice durante a manutenção do banco de dados. Esse recurso oferece mais flexibilidade aos administradores de banco de dados, pois permite que eles escolham entre reindexação offline e online, além de pausar e retomar a reconstrução do índice sempre que necessário.
Antes do lançamento do índice recuperável, os administradores de banco de dados podiam executar a reconstrução do índice offline e online .
Off-line oferece execução mais rápida, pois a tabela está bloqueada para qualquer leitura ou escrever operação e o novo índice é construído a partir do índice antigo. Durante esse processo, nenhuma operação de leitura ou gravação é permitida. Quando a operação é concluída, o bloqueio da tabela é liberado e as operações de leitura e gravação são permitidas novamente. O Off-line opção é naturalmente mais rápida.
On-line mantém a tabela aberta para ler e escrever operações. Há outra cópia do índice feita e todas as operações de reconstrução do índice estão nessa cópia. Todas as novas operações de linhas são gravadas em ambos os índices. Quando a reconstrução estiver concluída, a troca estará concluída e a nova cópia do índice será usada. O On-line A reconstrução permite operações de reconstrução enquanto o banco de dados está online. O tempo de inatividade é mínimo.
Observe que o recurso de índice retomável está disponível apenas na edição SQL Server Enterprise e na edição gratuita Developer. Se você tem essa opção na mesa, pode brincar com ela, fazer um teste simples e ver se esse recurso é útil no seu caso.
A documentação da Microsoft declara os seguintes aspectos para suas considerações:
- Você pode gerenciar, planejar e estender as janelas de manutenção do índice. Você pode pausar e reiniciar as operações de criação ou reconstrução de índice quando precisar ajustar suas janelas de manutenção.
- Você pode recuperar do índice criar ou reconstruir falhas (como failovers de banco de dados ou falta de espaço em disco).
- Observe que, quando uma operação de índice é pausada, tanto o índice original quanto o recém-criado exigirão espaço em disco. Você precisará atualizá-los durante as operações DML.
- Você pode ativar o truncamento de logs de transações durante as operações de criação ou reconstrução do índice.
- Observe que a opção SORT_IN_TEMPDB=ON não é compatível
Vamos testar a reconstrução do índice recuperável. Usarei uma imagem de contêiner executando a edição SQL 2019 Server Developer. Além disso, criarei uma pequena tabela com apenas algumas colunas e inserirei cerca de um milhão de linhas nessa tabela. Você pode fazer a tabela crescer com mais linhas.
Como estou usando uma máquina Linux e não consigo instalar o SQL Server Management Studio, usarei o cliente Azure Data Studio para me conectar ao meu SQL Server. Dê uma olhada na captura de tela das minhas propriedades do SQL Server:
Criaremos um banco de dados de exemplo, uma tabela e um índice com os scripts T-SQL abaixo. Você pode executá-los perfeitamente com SSMS ou dbForge Studio for 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
Para preencher a tabela com dados aleatórios, execute o script abaixo:
--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
Com uma tabela preenchida pronta, podemos prosseguir para o índice recuperável. Vamos começar com a criação desse índice:
-- 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
Observe novas opções/parâmetros no comando acima. RESUMABLE=ON significa que queremos ter uma operação de índice retomável. Max_Duration é o valor está em minutos definindo por quanto tempo queremos que a indexação seja executada.
Enquanto o comando acima estiver em execução, abra outra sessão e execute o comando T-SQL abaixo para PAUSE a atividade de reconstrução em curso:
--Rebuild WITH RESUMABLE functionality
ALTER INDEX IX_ID_Name ON [dbo].[TabletoIndex] PAUSE
GO
Se a PAUSA comando for bem-sucedido, pausamos a operação de indexação atual iniciada há cerca de um minuto. No entanto, quando você voltar para a sessão anterior para o comando de reconstrução com resumable=ON , ele retorna um erro feio. Eca. Mas sim, esse é o comportamento esperado.
Com essa reconstrução de índice recuperável, o SQL Server também introduziu um novo DMV sys.index_resumable_operations para verificar as operações pausadas. Vamos tentar olhar para este DMV:
A consulta de resultado DMV retorna meu comando de reconstrução de índice, a porcentagem concluída é ótima e muito mais. Quando todas as operações de reconstrução de índice forem concluídas, o DMV retornará vazio:
Bem legal, hein?
Mas e se você mudar de ideia sobre a mesa? E se houver uma alteração nos requisitos e você precisar fazer alterações no design do banco de dados? Vamos tentar descartar a tabela:
Ele dará outra mensagem de erro feia e longa:
Msg 10637, Nível 16, Estado 1, Linha 1
Não é possível executar esta operação em 'objeto' com ID 581577110, pois um ou mais índices estão atualmente em estado de reconstrução de índice recuperável. Consulte sys.index_resumable_operations para obter mais detalhes.
Tempo total de execução:00:00:00.018
A partir daqui, você perceberá que não tem escolha a não ser ABORTAR completamente a operação ou RETOMAR e deixar a reconstrução ser concluída.
Consulte o comando T-SQL para retomar ou abortar a operação. Então você pode descartar a tabela com sucesso:
ALTER INDEX IX_ID_Name ON [dbo].[TabletoIndex] RESUME
ALTER INDEX IX_ID_Name ON [dbo].[TabletoIndex] ABORT
O mesmo erro também ocorrerá se você precisar fazer outras operações, como descartar totalmente o índice ou encerrar a sessão atual.
Mas você se pergunta, é a opção retomável em primeiro lugar? A resposta é não. Para o SQL 2019, toda a criação de índice é com RESUMABLE=ON por padrão. É por causa dessas 2 declarações de escopo:
ALTER DATABASE SCOPED CONFIGURATION SET ELEVATE_ONLINE=WHEN_SUPPORTED ALTER DATABASE SCOPED CONFIGURATION SET ELEVATE_RESUMABLE=WHEN_SUPPORTED
Resumo
O impacto do uso da opção retomável no desempenho não é diferente do uso da operação de reindexação normal. O SQL Server apenas oferece mais controle sobre as operações de manutenção do banco de dados.
Quanto aos requisitos de reconstrução de índice de tabela periódica, a prática recomendada ainda é executar operações de índice offline ou pelo menos fora do horário de pico para garantir o mínimo impacto nos negócios.