Има няколко метода как да възстановите всички индекси на всички таблици в SQL Server, сред тях:
- Използване на планове за поддръжка на SQL Server.
- Използване на T-SQL скрипт въз основа на процента на фрагментация.
- Използване на команда ALTER INDEX.
В тази статия ще разгледаме тези методи и ще ги илюстрираме с практически примери.
1. План за поддръжка на индекс за възстановяване на SQL сървър
Първата опция за преглед е възстановяването на индекси с плановете за поддръжка на базата данни. Плановете за поддръжка са достъпни в папката за управление на SQL Server Management Studio.
За да създадете план за поддръжка на база данни на SQL, стартирайте SQL Server Management Studio > разширете екземпляра на базата данни > Управление > щракнете с десния бутон върху плана за поддръжка > Нов план за поддръжка .
Посочете името на плана за поддръжка. След това плъзнете и пуснете Задача за възстановяване на индекс в дизайнера на плана за поддръжка. Преименувайте задачата на Поддръжка на индекс .
Следващата стъпка е конфигурирането на плана за поддръжка. Щракнете двукратно върху него и конфигурирайте опциите в Задача за възстановяване на индекс както следва:
- Изберете AdventureWorks2017 база данни от падащото меню База(и) данни.
- За да създадете отново индекси на всички таблици, изберете Таблици и изгледи от Обект падащо меню.
- Поставете отметка до Сортиране на резултатите във tempdb .
- MAXDOP – набор2 (две).
- В нашия случай ще възстановим индекси само ако Фрагментацията стойността е по-висока от 20%. Затова задайте 20 в съответното поле.
- Щракнете върху OK за да запазите конфигурацията на индекса и да затворите Задачата за възстановяване на индекс прозорец.
Сега нека конфигурираме графика.
Кликнете върху календаря икона в горната част на дизайнера на плана за поддръжка:
Нов график за работа прозорец ще се отвори. Нека конфигурираме следните настройки:
- Изпълнявайте работата всеки ден. В Тип график меню, избираме Повтарящи се . След това в Честота раздел избираме Случва се > Ежедневно .
- Повтаря се всеки > 1 (ден).
- Дневна честота > Случва се веднъж в > посочете точното време. В нашия случай е 1 сутринта.
- Щракнете върху OK .
След това запазете плана за поддръжка.
Създадените планове за поддръжка са налични в SSMS План за поддръжка директория. За да видите графика, свързан с конкретния план за поддръжка, проверете Работа директория под SQL Server Agent .
За да тествате заданието, щракнете с десния бутон върху името му в Плановете за поддръжка директория и изберете Изпълни от менюто:
Изпълнението започва. Когато завърши успешно, ще видите следния диалогов прозорец:
Това беше обичайният метод за възстановяване на индекси с планове за поддръжка. Сега нека преминем към следващия метод – с помощта на T-SQL скриптовете.
2. Възстановяване на ALTER INDEX на SQL сървър
Командата ALTER INDEX може да се използва за възстановяване на всички индекси на таблицата. Синтаксисът е следният:
ALTER INDEX ALL ON [table_name] REBUILD
Забележка:име_на_таблица параметърът посочва името на таблицата, където искаме да възстановим всички индекси в SQL Server.
Например искаме да възстановим всички индекси на [HumanResources].[Служител] . Заявката трябва да бъде както следва:
use AdventureWorks2017
go
ALTER INDEX ALL ON [HumanResources].[Employee] REBUILD
Go
3. SQL сървърен скрипт за възстановяване на всички индекси за всички таблици въз основа на фрагментация
Поддръжката на индекса е ресурсоемка. Освен това той заключва таблицата, където възстановява индекса. За да избегнем подобни усложнения, трябва да изградим отново индекса, където фрагментацията на индекса на SQL Server е по-висока от 40%.
За да илюстрирам случая, създадох T-SQL скрипт, който възстановява индекси със степен на фрагментация по-висока от 30%. Нека разгледаме неговите части и функции.
Декларация на променливи и временна таблица
Първо, трябва да създадем временни таблици и променливи:
- @IndexFregQuery – съхранява динамичната заявка, използвана за попълване на фрагментирани индекси.
- @IndexRebuildQuery – съдържа заявката ALTER INDEX.
- @IndexName – името на индекса, което искаме да възстановим
- @Име на таблица – името на таблицата, където искаме да възстановим индекса.
- @SchemaName – името на схемата, където искаме да възстановим индекса.
- #Fregmentedindex – таблицата с 3 колони който съхранява името на индекса, името на таблицата и името на схемата.
Следният код декларира нашите променливи и временната таблица:
declare @i int=0
declare @IndexCount int
declare @IndexFregQuery nvarchar(max)
declare @IndexRebuildQuery nvarchar(max)
declare @IndexName varchar(500)
declare @TableName varchar(500)
declare @SchemaName varchar(500)
create table #Fregmentedindex(Index_name varchar(max),table_name varchar(max),schema_name varchar(max))
Вземете списъка с фрагментирани индекси
Следващата ни стъпка е да попълним списъка с индекси със степен на фрагментация от 30% или по-висока. Трябва да вмъкнем тези индекси в #FregmentedIndexes таблица.
Заявката трябва да попълни името на схемата, името на таблицата и името на индекса, за да ги вмъкне във временната таблица. Разгледайте тази заявка:
set @IndexFregQuery='SELECT i.[name],o.name,sch.name
FROM [' + @DatabaseName + '].sys.dm_db_index_physical_stats (DB_ID('''+ @DatabaseName +'''), NULL, NULL, NULL, NULL) AS s
INNER JOIN [' + @DatabaseName + '].sys.indexes AS i ON s.object_id = i.object_id AND s.index_id = i.index_id
INNER JOIN [' + @DatabaseName + '].sys.objects AS o ON i.object_id = o.object_id
INNER JOIN [' + @DatabaseName + '].sys.schemas AS sch ON o.schema_id=sch.schema_id
WHERE (s.avg_fragmentation_in_percent > 30 ) and i.name is not null'
insert into #Fregmentedindex(Index_name,table_name,schema_name) exec sp_executesql @IndexFregQuery
Създайте динамична SQL заявка
И накрая, трябва да изградим динамичния ALTER INDEX команда и я изпълнете.
За да генерираме командата, ние използваме цикъла WHILE. Преминава през #FregmentedIndexes таблица и попълва името на схемата, името на таблицата и името на индекса, за да ги запази в @SchemaName , @Име на таблица и @Име на индекс . Стойностите на параметрите се добавят в командата ALTER INDEX.
Кодът е следният:
set @IndexCount=(select count(1) from #Fregmentedindex)
While (@IndexCount>@i)
begin
(select top 1 @TableName=table_name, @IndexName=Index_name,@SchemaName= schema_name from #Fregmentedindex)
Set @IndexRebuildQuery ='Alter index [' + @IndexName +'] on ['[email protected] +'].['[email protected]+'].[' + @TableName +'] rebuild'
exec sp_executesql @IndexRebuildQuery
set @[email protected]+1
delete from #Fregmentedindex where [email protected] and [email protected]
End
Капсулирах целия код в sp_index_maintenance съхранена процедура, създадена в DBATools база данни. Кодът е следният:
use DBATools
go
Create procedure sp_index_maintenance_daily
@DatabaseName varchar(50)
as
begin
declare @i int=0
declare @IndexCount int
declare @IndexFregQuery nvarchar(max)
declare @IndexRebuildQuery nvarchar(max)
declare @IndexName varchar(500)
declare @TableName varchar(500)
declare @SchemaName varchar(500)
create table #Fregmentedindex(Index_name varchar(max),table_name varchar(max),schema_name varchar(max))
set @IndexFregQuery='SELECT i.[name],o.name,sch.name
FROM [' + @DatabaseName + '].sys.dm_db_index_physical_stats (DB_ID('''+ @DatabaseName +'''), NULL, NULL, NULL, NULL) AS s
INNER JOIN [' + @DatabaseName + '].sys.indexes AS i ON s.object_id = i.object_id AND s.index_id = i.index_id
INNER JOIN [' + @DatabaseName + '].sys.objects AS o ON i.object_id = o.object_id
INNER JOIN [' + @DatabaseName + '].sys.schemas AS sch ON o.schema_id=sch.schema_id
WHERE (s.avg_fragmentation_in_percent > 30 ) and i.name is not null'
insert into #Fregmentedindex(Index_name,table_name,schema_name) exec sp_executesql @IndexFregQuery
set @IndexCount=(select count(1) from #Fregmentedindex)
While (@IndexCount>@i)
begin
(select top 1 @TableName=table_name, @IndexName=Index_name,@SchemaName= schema_name from #Fregmentedindex)
Set @IndexRebuildQuery ='Alter index [' + @IndexName +'] on ['[email protected] +'].['[email protected]+'].[' + @TableName +'] rebuild'
exec sp_executesql @IndexRebuildQuery
set @[email protected]+1
delete from #Fregmentedindex where [email protected] and [email protected]
End
End
След като процедурата е готова, можем да конфигурираме SQL заданието.
Разгънете SQL Server Agent > щракнете с десния бутон върху Работни места > Нова работа .
Новата работа се отваря прозорец, където трябва да посочите желаното име на заданието.
За да създадете стъпка на задание, отидете до Стъпки раздел> Ново бутон:
Ще стигнете до Стъпка за нова работа прозорец, за да конфигурирате тази стъпка.
Въведете желаното име на стъпка и въведете следния код в текстовото поле:
use DBATools
go
exec sp_index_maintenance_daily 'AdventureWorks2017'
За да конфигурирате графика, отидете на Графици > щракнете върху Ново .
Нашата работа трябва да бъде изпълнена в 1:00 часа сутринта. Съответно ние конфигурираме графика:
- Тип график > Повтарящи се .
- Честотата раздел> Случва се > Ежедневно ; Повтаря се всеки > 1 (един).
- Дневната честота раздел> Среща се веднъж в > 01:00:00.
- Щракнете върху OK .
Ще бъдете прехвърлени обратно на Нова работа раздел. Щракнете върху OK там също, за да създадете заданието.
Новосъздаденото задание е достъпно в Работа директория под SQL Server Agent папка.
Сега трябва да тестваме заданието:щракнете с десния бутон върху него и изберете Стартиране на задача...
Задачата започва и при успешно завършване ще видите следното съобщение:
Ако сравним клъстериран индекс с неклъстериран индекс, ще видим, че създаването на уникален клъстериран индекс увеличава ефективността на изпълнението на заявката. Индексираните изгледи в SQL Server могат да се използват за ускоряване на изпълнението на заявката. Вижте също как да управлявате индекси с помощта на SQL Index Manager.
Резюме
Настоящата статия представя три функционални начина за възстановяване на индекси на всички таблици. Разгледахме ги всички с насоки стъпка по стъпка и практически примери за SQL индекси, за да илюстрираме конфигурацията на заданието. Изборът на подходящия вариант е ваш и се надяваме, че тази статия ви е била полезна.