SQL 2017 wprowadził możliwość wstrzymywania i wznawiania operacji odbudowy indeksu podczas konserwacji bazy danych. Ta funkcja zapewnia większą elastyczność administratorom baz danych, ponieważ umożliwia im wybór między ponownym indeksowaniem offline i online oraz wstrzymywanie i wznawianie odbudowy indeksu w razie potrzeby.
Przed wydaniem indeksu wznawialnego administratorzy baz danych mogli wykonać odbudowę indeksu offline i online .
Offline oferuje szybsze wykonanie, ponieważ tabela jest zablokowana dla każdego odczytu lub napisz operacji, a nowy indeks jest budowany na podstawie starego indeksu. Podczas tego procesu nie jest dozwolona żadna operacja odczytu ani zapisu. Po zakończeniu operacji blokada tabeli jest zwalniana, a operacje odczytu i zapisu są ponownie dozwolone. Offline opcja jest naturalnie szybsza.
Online utrzymuje stół otwarty do czytania i pisać operacje. Jest wykonana inna kopia indeksu i wszystkie operacje odbudowy indeksu znajdują się w tej kopii. Wszystkie nowe operacje na wierszach są zapisywane w obu indeksach. Po zakończeniu odbudowy przełączanie jest zakończone i nowa kopia indeksu jest używana. Online rebuild pozwala na operacje odbudowy, gdy baza danych jest w trybie online. Przestój jest minimalny.
Należy zauważyć, że funkcja wznawiania indeksu jest dostępna tylko w wersji SQL Server Enterprise i bezpłatnej wersji Developer. Jeśli masz tę opcję na stole, możesz się nią pobawić, wykonać prosty test i sprawdzić, czy ta funkcja jest przydatna w Twoim przypadku.
Dokumentacja firmy Microsoft zawiera następujące aspekty do rozważenia:
- Możesz zarządzać, planować i rozszerzać okna obsługi indeksu. Możesz wstrzymać i ponownie uruchomić operacje tworzenia lub odbudowy indeksu, gdy musisz dopasować okna obsługi.
- Możesz odzyskać dane po błędach tworzenia lub odbudowy indeksu (takich jak przełączenie awaryjne bazy danych lub brak miejsca na dysku).
- Zwróć uwagę, że po wstrzymaniu operacji indeksowania zarówno indeks oryginalny, jak i nowo utworzony będą wymagały miejsca na dysku. Będziesz musiał je zaktualizować podczas operacji DML.
- Możesz włączyć obcinanie dzienników transakcji podczas operacji tworzenia lub odbudowy indeksu.
- Pamiętaj, że opcja SORT_IN_TEMPDB=ON nie jest obsługiwana
Przetestujmy odbudowę indeksu wznawialnego. Użyję obrazu kontenera z uruchomioną edycją SQL 2019 Server Developer. Ponadto utworzę małą tabelkę z zaledwie kilkoma kolumnami i wstawię do niej około miliona wierszy. Możesz powiększyć tabelę za pomocą większej liczby rzędów.
Ponieważ używam komputera z systemem Linux i nie mogę zainstalować programu SQL Server Management Studio, do łączenia się z moim programem SQL Server użyję klienta Azure Data Studio. Spójrz na zrzut ekranu moich właściwości SQL Server:
Stworzymy przykładową bazę danych, tabelę i indeks za pomocą poniższych skryptów T-SQL. Możesz je wykonać bezbłędnie za pomocą SSMS lub dbForge Studio dla 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
Aby wypełnić tabelę losowymi danymi, wykonaj poniższy skrypt:
--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
Mając już wypełnioną tabelę, możemy przejść do indeksu, który można wznowić. Zacznijmy od stworzenia tego indeksu:
-- 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
Zwróć uwagę na nowe opcje/parametry w powyższym poleceniu. RESUMABLE=WŁ oznacza, że chcemy mieć wznawianą operację indeksowania. Maksymalny czas trwania to wartość w minutach określająca, jak długo indeksowanie ma być wykonywane.
Gdy powyższe polecenie jest uruchomione, otwórz kolejną sesję i wykonaj poniższe polecenie T-SQL, aby PAUZA trwająca przebudowa:
--Rebuild WITH RESUMABLE functionality
ALTER INDEX IX_ID_Name ON [dbo].[TabletoIndex] PAUSE
GO
Jeśli PAUZA polecenie zakończyło się pomyślnie, wstrzymujemy bieżącą operację indeksowania rozpoczętą około minutę temu. Jednak po powrocie do poprzedniej sesji w celu wykonania polecenia odbudowy z resumable=ON , zwraca brzydki błąd. Uch. Ale tak, to jest oczekiwane zachowanie.
Dzięki tej odbudowie indeksu z możliwością wznawiania, SQL Server wprowadził również nowy DMV sys.index_resumable_operations aby sprawdzić wstrzymane operacje. Spróbujmy przyjrzeć się temu DMV:
Zapytanie wynikowe DMV zwraca moje polecenie odbudowy indeksu, procent ukończenia to świetna rzecz i nie tylko. Po zakończeniu wszystkich operacji odbudowy indeksu, DMV zwraca puste:
Całkiem fajnie, co?
Ale co, jeśli zmienisz zdanie na temat stołu? Co by było, gdyby nastąpiła zmiana wymagań i trzeba wprowadzić zmiany w projekcie bazy danych? Spróbujmy upuścić tabelę:
Spowoduje to kolejny brzydki, długi komunikat o błędzie:
Wiadomość 10637, poziom 16, stan 1, wiersz 1
Nie można wykonać tej operacji na „obiekcie” o identyfikatorze 581577110, ponieważ co najmniej jeden indeks jest obecnie w stanie odbudowy indeksu, który można wznowić. Więcej informacji można znaleźć w sys.index_resumable_operations.
Całkowity czas wykonania:00:00:00.018
Od tego momentu zdasz sobie sprawę, że nie masz wyboru, jak tylko całkowicie PRZERWAĆ operację lub WZNOWIĆ i pozwolić, aby odbudowa się zakończyła.
Zobacz polecenie T-SQL, aby wznowić lub przerwać operację. Następnie możesz pomyślnie upuścić tabelę:
ALTER INDEX IX_ID_Name ON [dbo].[TabletoIndex] RESUME
ALTER INDEX IX_ID_Name ON [dbo].[TabletoIndex] ABORT
Ten sam błąd wystąpi również, jeśli będziesz musiał wykonać inne operacje, takie jak całkowite usunięcie indeksu lub zakończenie bieżącej sesji.
Ale zadajesz sobie pytanie, czy opcja wznowienia jest w pierwszej kolejności? Odpowiedź brzmi nie. W przypadku SQL 2019 wszystkie tworzenie indeksów ma domyślnie wartość RESUMABLE=ON. Dzieje się tak z powodu tych 2 deklaracji zakresu:
ALTER DATABASE SCOPED CONFIGURATION SET ELEVATE_ONLINE=WHEN_SUPPORTED ALTER DATABASE SCOPED CONFIGURATION SET ELEVATE_RESUMABLE=WHEN_SUPPORTED
Podsumowanie
Wpływ korzystania z opcji wznawiania na wydajność nie różni się od korzystania z normalnej operacji ponownego indeksowania. SQL Server zapewnia po prostu większą kontrolę nad operacjami konserwacji bazy danych.
Jeśli chodzi o wymagania dotyczące okresowej odbudowy indeksu tabeli, najlepszą praktyką jest nadal uruchamianie operacji indeksowania w trybie offline lub przynajmniej poza godzinami szczytu, aby zapewnić minimalny wpływ na działalność.