ALTER INDEX (Transact-SQL)
Изменяет существующий индекс таблицы или представления (реляционного или XML) посредством отключения, перестройки или реорганизации либо посредством настройки параметров индекса.
ALTER INDEX { index_name | ALL }
ON <object>
{ REBUILD
[ [PARTITION = ALL]
[ WITH ( <rebuild_index_option> [ ,...n ] ) ]
| [ PARTITION =partition_number
[ WITH ( <single_partition_rebuild_index_option>
[ ,...n ] )
]
]
]
| DISABLE
| REORGANIZE
[ PARTITION =partition_number ]
[ WITH ( LOB_COMPACTION = { ON | OFF } ) ]
| SET ( <set_index_option> [ ,...n ] )
}
[ ; ]
<object> ::=
{
[ database_name. [ schema_name ] . | schema_name. ]
table_or_view_name
}
<rebuild_index_option > ::=
{
PAD_INDEX = { ON | OFF }
| FILLFACTOR =fillfactor
| SORT_IN_TEMPDB = { ON | OFF }
| IGNORE_DUP_KEY = { ON | OFF }
| STATISTICS_NORECOMPUTE = { ON | OFF }
| ONLINE = { ON | OFF }
| ALLOW_ROW_LOCKS = { ON | OFF }
| ALLOW_PAGE_LOCKS = { ON | OFF }
| MAXDOP =max_degree_of_parallelism
| DATA_COMPRESSION = { NONE | ROW | PAGE }
[ ON PARTITIONS ( { <partition_number_expression> | <range> }
[ , ...n ] ) ]
}
<range> ::=
<partition_number_expression> TO <partition_number_expression>
}
<single_partition_rebuild_index_option> ::=
{
SORT_IN_TEMPDB = { ON | OFF }
| MAXDOP =max_degree_of_parallelism
| DATA_COMPRESSION = { NONE | ROW | PAGE } }
}
<set_index_option>::=
{
ALLOW_ROW_LOCKS = { ON | OFF }
| ALLOW_PAGE_LOCKS = { ON | OFF }
| IGNORE_DUP_KEY = { ON | OFF }
| STATISTICS_NORECOMPUTE = { ON | OFF }
}
Инструкция ALTER INDEX не может использоваться для повторного секционирования индекса или его перемещения в другую файловую группу. Эта инструкция не может использоваться для изменения определения индекса, в том числе добавления или удаления столбцов или изменения порядка столбцов. Для выполнения этих операций следует использовать инструкцию CREATE INDEX с предложением DROP_EXISTING.
Если параметр не указан явно, то применяется текущий параметр. Например, если параметр FILLFACTOR не указан в предложении REBUILD, то коэффициент заполнения, сохраненный в системном каталоге, будет использоваться в процессе перестроения. Для просмотра текущего параметра индекса следует использовать таблицу sys.indexes.
Примечание
|
|---|
|
Значения для параметров ONLINE, MAXDOP и SORT_IN_TEMPDB не хранятся в системном каталоге. Если значение некоторого параметра не указано в инструкции индекса, то используется значение по умолчанию. |
В компьютерах с несколькими процессорами инструкция ALTER INDEX REBUILD, как и другие запросы, использует больше процессоров для операций просмотра и сортировки, связанных с изменением индекса. При выполнении инструкции ALTER INDEX REORGANIZE, без предложения LOB_COMPACTION или с ним, значение аргумента max degree of parallelism представляет собой однопотоковую операцию. Дополнительные сведения см. в разделе Настройка параллельных операций с индексами.
Индекс нельзя реорганизовать или перестроить, если файловая группа, в которой он находится, размещена вне сети или предназначена только для чтения. Если указывается ключевое слово ALL, а один или несколько индексов находятся в файловой группе, которая размещена вне сети или предназначена только для чтения, то выполнить инструкцию не удастся.
Восстановление индексов
При перестроении старый индекс удаляется, и повторно создается новый. Таким образом, устраняется фрагментация, восстанавливается место на диске путем сжатия страниц с учетом указанного или существующего коэффициента заполнения, переупорядочиваются индексные строки в последовательных страницах. Если указывается ключевое слово ALL, то все индексы для таблицы удаляются и перестраиваются в одной транзакции. Ограничения FOREIGN KEY не обязательно отменять заранее. Если перестраиваются индексы с 128 или большим числом экстентов, то компонент Database Engine откладывает процедуры освобождения страниц и связанные с ними блокировки до фиксации транзакции. Дополнительные сведения см. в разделе Удаление и повторная сборка больших объектов.
Примечание
|
|---|
|
Перестроение или реорганизация малых индексов часто не приводит к уменьшению фрагментации. Страницы индексов малого размера хранятся в смешанных экстентах. Смешанные экстенты могут находиться в общем пользовании у восьми объектов, поэтому фрагментацию в малом индексе нельзя уменьшить путем его реорганизации или перестроения. Дополнительные сведения о смешанных экстентах см. в разделе Страницы и экстенты. |
В предыдущих версиях SQL Server иногда можно было перестроить некластеризованный индекс, чтобы исправить любые несоответствия, вызванные отказами оборудования. В SQL Server 2008 по-прежнему можно скорректировать такие несоответствия между индексом и кластеризованным индексом, перестроив некластеризованный индекс в режиме вне сети. Однако нельзя устранить несоответствия некластеризованного индекса, перестроив индекс в режиме в сети, потому что механизм перестроения в этом режиме будет использовать существующий некластеризованный индекс в качестве основы для перестроения и тем самым закрепит несоответствие. При перестроении индекса вне сети, в отличие от вышесказанного, принудительно запускается просмотр кластеризованного индекса (или кучи) и в результате устраняются несоответствия. В предыдущих версиях рекомендованным методом устранения несоответствий было восстановление неправильных данных из резервных копий, однако исправить несоответствия индекса можно, перестроив некластеризованный индекс в режиме «вне сети». Дополнительные сведения см. в разделе DBCC CHECKDB (Transact-SQL).
Реорганизация индексов
Для реорганизации индекса требуется минимальный объем системных ресурсов. Дефрагментируется конечный уровень кластеризованного и некластеризованного индексов для таблиц и представлений путем физического переупорядочения страниц на конечном уровне в соответствии с логическим, слева направо, порядком конечных узлов. Кроме того, реорганизация сжимает страницы индекса. Их сжатие производится в соответствии с текущим значением коэффициента заполнения. Просмотреть коэффициент заполнения можно в таблице sys.indexes.
Если указывается ключевое слово ALL, то реляционные индексы, как кластеризованные, так и некластеризованные, и XML-индексы для таблицы реорганизуются. Существуют некоторые ограничения при указании ключевого слова ALL, см. определение ALL в разделе «Аргументы».
Дополнительные сведения см. в разделе Реорганизация и перестроение индексов.
Отключение индексов
Отключение индексов предотвращает доступ пользователя к индексам в случае использования кластеризованных индексов к данным базовой таблицы. Определение индекса остается в системном каталоге. Отключение некластеризованных индексов или кластеризованных индексов в представлении физически удаляет данные индекса. При отключении кластеризованного индекса блокируется доступ к данным, но данные остаются необслуживаемыми в сбалансированном дереве до тех пор, пока индекс не будет удален или перестроен. Для просмотра состояния включенного или отключенного индекса следует направить запрос в столбец is_disabled в представлении каталога sys.indexes.
Если таблица является публикацией репликации транзакций, то нельзя отключать индексы, связанные со столбцами первичного ключа. Эти индексы необходимы для репликации. Чтобы отключить индексы, сначала необходимо удалить таблицу из публикации. Дополнительные сведения см. в разделе Публикация данных и объектов базы данных.
Для активизации индекса следует использовать инструкцию ALTER INDEX REBUILD или инструкцию CREATE INDEX WITH DROP_EXISTING. Перестроить отключенный кластеризованный индекс нельзя, если параметр ONLINE установлен в ON. Дополнительные сведения см. в разделе Отключение индексов.
Установка параметров
Можно установить параметры ALLOW_ROW_LOCKS, ALLOW_PAGE_LOCKS, IGNORE_DUP_KEY и STATISTICS_NORECOMPUTE для конкретного индекса без перестройки или реорганизации этого индекса. Измененные значения немедленно применяются к индексу. Для просмотра этих установок следует использовать таблицу sys.indexes. Дополнительные сведения см. в разделе Установка параметров индекса.
Параметры блокировок строк и страниц
Когда присвоены значения ALLOW_ROW_LOCKS = ON и ALLOW_PAGE_LOCK = ON, при доступе к индексу допустимы блокировки на уровне строк, уровне страниц и уровне таблиц. Компонент Database Engine выберет соответствующую блокировку и может повысить уровень блокировки с уровня строки или таблицы до уровня страницы.
Если присвоены значения ALLOW_ROW_LOCKS = OFF и ALLOW_PAGE_LOCK = OFF, при доступе к индексу допустима только блокировка на уровне таблиц. Дополнительные сведения о настройке гранулярности блокировки индекса см. в разделе Настройка блокировки индекса.
Если при установке параметров блокировки строки или страницы указывается ключевое слово ALL, то установки применяются ко всем индексам. Если базовая таблица представляет собой кучу, установки применяются следующими способами:
|
ALLOW_ROW_LOCKS = ON или OFF |
Для кучи и любых соответствующих некластеризованных индексов. |
|
ALLOW_PAGE_LOCKS = ON |
Для кучи и любых соответствующих некластеризованных индексов. |
|
ALLOW_PAGE_LOCKS = OFF |
Полностью для некластеризованных индексов. Это означает, что все блокировки страниц запрещаются для некластеризованных индексов. В куче запрещены только общая блокировка (S), блокировка обновления (U) и монопольная блокировка (X) для страниц. Компонент Database Engine может запросить намеренную блокировку страницы (IS, IU или IX) для внутренних целей. |
Дополнительные сведения см. в разделе Укрупнение блокировки (компонент Database Engine).
Операция с индексами в сети
Если при перестройке индекса параметр ONLINE установлен в значение ON, то базовые объекты, таблицы и связанные с ними индексы доступны для запросов и изменения данных. Монопольные блокировки таблиц удерживаются лишь на очень короткое время в процессе изменения.
Реорганизация индекса всегда выполняется в режиме в сети. Процесс не удерживает блокировку в течение долгого времени и поэтому не блокирует выполняемые запросы и обновления.
Параллельные операции с индексами в сети для одной таблицы можно выполнять лишь при выполнении следующих действий:
-
создание нескольких некластеризованных индексов;
-
реорганизация различных индексов в одной таблице;
-
реорганизация различных индексов при перестройке неперекрывающихся индексов в одной таблице.
Все остальные попытки выполнения операций с индексами в сети завершаются ошибкой. Например, нельзя одновременно перестроить два или несколько индексов в одной таблице или создать новый индекс в процессе перестройки существующего индекса для этой таблицы.
Дополнительные сведения см. в разделе Выполнение операции с индексами в сети.
Ограничения пространственного индекса
При перестроении пространственного индекса базовая пользовательская таблица недоступна на протяжении выполнения операции с индексом, поскольку пространственный индекс блокирует схему.
Ограничение PRIMARY KEY в пользовательской таблице не может быть изменено, пока для столбца этой таблицы определен пространственный индекс. Для изменения ограничения PRIMARY KEY сначала необходимо удалить все пространственные индексы таблицы. После изменения ограничения PRIMARY KEY все пространственные индексы можно создать повторно.
В отдельной операции перестроения секции невозможно указать пространственные индексы. Однако пространственные индексы можно указать при полном перестроении секции.
Чтобы изменить параметры, характерные для пространственного индекса (такие как BOUNDING_BOX или GRID), необходимо либо применить инструкцию CREATE SPATIAL INDEX с параметром DROP_EXISTING = ON, либо удалить пространственный индекс и создать новый. См. пример в разделе CREATE SPATIAL INDEX (Transact-SQL).
Сжатие данных
Дополнительные сведения о сжатии данных см. в разделе Создание сжатых таблиц и индексов.
Оценить состояние сжатия таблицы, индекса или секции можно с помощью хранимой процедуры sp_estimate_data_compression_savings.
На секционированные индексы налагаются следующие ограничения.
-
Если у таблицы есть невыровненные индексы, то изменить настройку сжатия отдельной секции с помощью инструкции ALTER INDEX ALL невозможно.
-
Инструкция ALTER INDEX <index> ... Инструкция REBUILD PARTITION ... производит перестроение указанной секции индекса.
-
Инструкция ALTER INDEX <index> ... Инструкция REBUILD WITH ... производит перестроение всех секций индекса.
А. Перестроение индекса
В следующем примере перестраивается один индекс в таблице Employee.
USE AdventureWorks2008R2; GO ALTER INDEX PK_Employee_BusinessEntityID ON HumanResources.Employee REBUILD; GO
Б. Перестроение всех индексов по таблице и указание параметров
В нижеследующем примере указывается ключевое слово ALL. Тем самым выполняется перестроение всех индексов, связанных с таблицей. Указываются три параметра.
USE AdventureWorks2008R2;
GO
ALTER INDEX ALL ON Production.Product
REBUILD WITH (FILLFACTOR = 80, SORT_IN_TEMPDB = ON,
STATISTICS_NORECOMPUTE = ON);
GO
В. Реорганизация индекса со сжатием LOB
В нижеследующем примере производится реорганизация отдельного кластеризованного индекса. Поскольку индекс содержит тип данных LOB на конечном уровне, инструкция также подвергает сжатию все страницы, в которых содержатся данные больших объектов. Следует отметить, что указывать параметр WITH (LOB_COMPACTION) не требуется, так как значение по умолчанию — ON.
USE AdventureWorks2008R2; GO ALTER INDEX PK_ProductPhoto_ProductPhotoID ON Production.ProductPhoto REORGANIZE ; GO
Г. Назначение параметров для индекса
В следующем примере устанавливаются несколько параметров для индекса AK_SalesOrderHeader_SalesOrderNumber.
USE AdventureWorks2008R2;
GO
ALTER INDEX AK_SalesOrderHeader_SalesOrderNumber ON
Sales.SalesOrderHeader
SET (
STATISTICS_NORECOMPUTE = ON,
IGNORE_DUP_KEY = ON,
ALLOW_PAGE_LOCKS = ON
) ;
GO
Д. Отключение индекса
В следующем примере отключается некластеризованный индекс в таблице Employee.
USE AdventureWorks2008R2; GO ALTER INDEX IX_Employee_OrganizationNode ON HumanResources.Employee DISABLE ; GO
Е. Снятие ограничений
В следующем примере снимается ограничение PRIMARY KEY путем отключения индекса PRIMARY KEY. Ограничение FOREIGN KEY в базовой таблице автоматически отключается, и выводится предупредительное сообщение.
USE AdventureWorks2008R2; GO ALTER INDEX PK_Department_DepartmentID ON HumanResources.Department DISABLE ; GO
Результирующий набор возвращает это предупреждающее сообщение.
Warning: Foreign key 'FK_EmployeeDepartmentHistory_Department_DepartmentID'
on table 'EmployeeDepartmentHistory' referencing table 'Department'
was disabled as a result of disabling the index 'PK_Department_DepartmentID'.
Ж. Активация ограничений
В следующем примере активируются ограничения PRIMARY KEY и FOREIGN KEY, снятые в примере Е.
Ограничение PRIMARY KEY активируется путем перестройки индекса PRIMARY KEY.
USE AdventureWorks2008R2; GO ALTER INDEX PK_Department_DepartmentID ON HumanResources.Department REBUILD ; GO
Затем активируется ограничение FOREIGN KEY.
ALTER TABLE HumanResources.EmployeeDepartmentHistory CHECK CONSTRAINT FK_EmployeeDepartmentHistory_Department_DepartmentID; GO
З. Перестройка секционированного индекса
В следующем примере перестраивается одиночная секция, секция номер 5 секционированного индекса IX_TransactionHistory_TransactionDate. В данном примере подразумевается, что образец секционированного индекса установлен.
USE AdventureWorks2008R2; GO -- Verify the partitioned indexes. SELECT * FROM sys.dm_db_index_physical_stats (DB_ID(),OBJECT_ID(N'Production.TransactionHistory'), NULL , NULL, NULL); GO --Rebuild only partition 5. ALTER INDEX IX_TransactionHistory_TransactionDate ON Production.TransactionHistory REBUILD Partition = 5; GO
И. Изменение настроек сжатия индекса
В следующем примере перестраивается индекс в несекционированной таблице.
ALTER INDEX IX_INDEX1 ON T1 REBUILD WITH ( DATA_COMPRESSION = PAGE ) GO
Дополнительные примеры сжатия данных см. в разделе Создание сжатых таблиц и индексов.
