Будьте осторожны, ребята. Кластерный индекс - это другое животное, когда дело доходит до больших объектов. Давайте сделаем тест, чтобы понять, что я имею в виду.
Сначала давайте настроим тестовую таблицу. Для этого теста данные не нужны, но у нас есть кластерный индекс (IndexID = 1) в качестве PK. У нас также есть некластеризованный индекс (IndexID = 2), который не содержит столбцы больших объектов как INCLUDE, и у нас также есть некластеризованный индекс, который содержит столбец больших объектов как INCLUDE. Вот код настройки теста ...
--========================================================================
-- Test Setup
--========================================================================
--===== If the test table already exists,
-- drop it to make reruns in SSMS easier.
IF OBJECT_ID('dbo.IndexTest','U') IS NOT NULL
DROP TABLE dbo.IndexTest
;
GO
--===== Create the test table
CREATE TABLE dbo.IndexTest
(
SomeID INT IDENTITY(1,1)
,SomeInt INT
,SomeLOB1 VARCHAR(MAX)
,CONSTRAINT PK_IndexTest_Has_LOB
PRIMARY KEY CLUSTERED (SomeID)
)
;
--===== Add an index that has no INCLUDE of a LOB
CREATE INDEX IX_Has_No_LOB
ON dbo.IndexTest (SomeInt)
;
--===== Add an index that has INCLUDEs a LOB
CREATE INDEX IX_Includes_A_LOB
ON dbo.IndexTest (SomeInt) INCLUDE (SomeLOB1)
;
Теперь давайте попробуем код, который использует sys.index_columns для поиска индексов, которые содержат большие объекты. Я закомментировал system_type_id в предложении WHERE, чтобы открыть его немного ...
--========================================================================
-- Test for LOBs using sys.index_columns.
--========================================================================
select distinct
si.*
from
sys.indexes as si
inner join sys.index_columns as ic on
ic.object_id = si.object_id and
ic.index_id = si.index_id
inner join sys.columns as sc on
sc.object_id = ic.object_id and
sc.column_id = ic.column_id
where
--sc.system_type_id = 167 and
sc.max_length = -1
;
Вот вывод из цикла выше ...
object_id name index_id type type_desc ...
----------- ----------------- ----------- ---- ------------ ...
163204448 IX_Includes_A_LOB 3 2 NONCLUSTERED ...
Невозможно сказать, что кластерный индекс содержит большой объект, поскольку большой объект не является одним из столбцов индекса. Попытка перестроить этот кластерный индекс приведет к сбою.
ALTER INDEX PK_IndexTest_Has_LOB
ON dbo.IndexTest REBUILD WITH (ONLINE = ON)
;
Сообщение 2725, уровень 16, состояние 2, строка 1 Операция индексирования в сети не может быть
выполняется для индекса 'PK_IndexTest_Has_LOB', поскольку индекс содержит
столбец «SomeLOB1» типа данных text, ntext, image, varchar (max),
nvarchar (max), varbinary (max) или xml. Для некластеризованного индекса
столбец может быть столбцом включения индекса, для кластеризованного индекса -
может быть любой столбец таблицы. В случае drop_existing столбца
может быть частью нового или старого индекса. Операция должна быть выполнена
в автономном режиме.
С кончиком шляпы Ремусу Русану (система не разрешила мне опубликовать ссылку) ...
... мы можем попробовать что-то немного другое. Каждый индекс (кластеризованный, некластеризованный или HEAP) отображается как единица выделения, а также идентифицирует данные в строке, данные вне строки и большие объекты. Следующий код находит ВСЕ индексы, с которыми связан большой объект ... даже Кластерный индекс.
--===== Find all indexes that contain any type of LOB
SELECT SchemaName = OBJECT_SCHEMA_NAME(p.object_id)
,ObjectName = OBJECT_NAME(p.object_id)
,IndexName = si.name
,p.object_id
,p.index_id
,au.type_desc
FROM sys.system_internals_allocation_units au --Has allocation type
JOIN sys.system_internals_partitions p --Has an Index_ID
ON au.container_id = p.partition_id
JOIN sys.indexes si --For the name of the index
ON si.object_id = p.object_id
AND si.index_id = p.index_id
WHERE p.object_id = OBJECT_ID('IndexTest')
AND au.type_desc = 'LOB_DATA'
;
Это дает следующий вывод для этого конкретного теста. Обратите внимание на то, что он обнаружил кластеризованный индекс по object_id и index_id, где код, основанный на sys.index_columns, не смог.
SchemaName ObjectName IndexName object_id index_id type_desc
---------- ---------- -------------------- --------- -------- ---------
dbo IndexTest PK_IndexTest_Has_LOB 163204448 1 LOB_DATA
dbo IndexTest IX_Includes_A_LOB 163204448 3 LOB_DATA