Attention, les gens. L'index clusterisé est un animal différent quand il s'agit de LOBs. Faisons un test pour voir ce que je veux dire.
Tout d'abord, configurons une table de test. Aucune donnée n'est nécessaire pour ce test mais nous avons un index clusterisé (IndexID = 1) comme PK. Nous avons également un Index Non Clustered (IndexID = 2) qui ne contient aucune colonne LOB en tant que INCLUDE et nous avons également un Index Non Clustered qui contient une colonne LOB en tant que INCLUDE. Voici le code de configuration de test ...
--========================================================================
-- 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)
;
Maintenant, nous allons essayer le code qui utilise sys.index_columns pour trouver des indices qui contiennent LOB. Je l'ai commenté le system_type_id dans la clause WHERE pour l'ouvrir un peu ...
--========================================================================
-- 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
;
est ici la sortie de la course ci-dessus ...
object_id name index_id type type_desc ...
----------- ----------------- ----------- ---- ------------ ...
163204448 IX_Includes_A_LOB 3 2 NONCLUSTERED ...
Il ne pouvait pas dire que l'index cluster contient un objet LOB car le LOB n'est pas l'une des colonnes d'index. Essayer de reconstruire cet index clusterisé provoquera un échec.
ALTER INDEX PK_IndexTest_Has_LOB
ON dbo.IndexTest REBUILD WITH (ONLINE = ON)
;
Msg 2725, niveau 16, état 2, opération d'index en ligne ligne 1 ne peut pas être réalisée pour l'indice 'PK_IndexTest_Has_LOB' parce que l'index contient colonne 'SomeLOB1' du texte de type de données, ntext, image, varchar (max), nvarchar (max), varbinary (max) ou xml. Pour les index non clusterisés, la colonne peut être une colonne include de l'index, pour l'index clusterisé, peut être n'importe quelle colonne de la table.En cas de drop_existing, la colonne pourrait faire partie d'un index nouveau ou ancien. L'opération doit être effectuée hors ligne.
Avec une pointe du chapeau à Remus Rusanu (système ne me laisse pas poster le lien) ...
... nous pouvons essayer quelque chose d'un peu différent. Chaque index (clusterisé, non clusterisé ou HEAP) apparaît comme une unité d'allocation et identifie également les données dans la rangée, les données hors ligne et les objets LOB. Le code suivant trouve tous les index qui ont un métier associé ... même l'index groupé.
--===== 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'
;
Cela produit la sortie suivante pour ce test particulier. Notez qu'il a détecté l'index cluster par object_id et index_id, contrairement au code basé sur 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
Merci, je pense que ça va faire l'affaire –
Fèves fraîches. Je savais que c'était quelque chose avec -1 et la longueur. –