Microsoft SQL Server インデックスを削除/作成/無効化/有効化 (再構築) するために私が思いついたのは次のとおりです。
CREATE VIEW dbo.vw_INDEX_TEXT AS
SELECT
x.[owner_name],
x.[table_name],
x.[index_name],
/*
** DROP index
*/
drop_sql = 'DROP INDEX ' + x.[index_name] + ' ON ' + x.[owner_name] + '.' + x.[table_name] + ';',
/*
** CREATE index
*/
create_sql =
'CREATE NONCLUSTERED INDEX ' + x.[index_name] + '
ON ' + x.[owner_name] + '.' + x.[table_name] + '(' +
-- the common-delimited field list.
substring(
(SELECT
',' + [field_name]
FROM
(
SELECT
[owner_name] = SCHEMA_NAME(O.schema_id),
[table_name] = O.name,
[index_name] = I.name,
[field_name] = C.name,
O.type,
S.key_ordinal,
S.is_descending_key,
S.is_included_column
FROM
sys.all_objects O inner join sys.indexes I ON (O.object_id = I.object_id )
inner join sys.index_columns S ON (O.object_id = S.object_id and I.index_id=S.index_id)
inner join sys.columns C ON (O.object_id = C.object_id and S.column_id = C.column_id)
WHERE
I.index_id > 0
AND SCHEMA_NAME(O.schema_id) = x.[owner_name] -- N'dbo'
AND I.name = x.[index_name] -- the index name N'IDX_myindex'
AND O.name = x.[table_name] -- the base table name N'mytable'
AND O.type <> 'IT'
AND I.is_primary_key = 0 -- we are not creating primary keys
AND I.is_unique_constraint = 0 -- we are not creating unique constraints
AND (INDEXPROPERTY(I.object_id,I.name,'IsStatistics') <> 1)
AND (INDEXPROPERTY(I.object_id,I.name,'IsAutoStatistics') <> 1)
AND (INDEXPROPERTY(I.object_id,I.name,'IsHypothetical') <> 1)
) as f
FOR XML PATH('')
), 2, 8000) -- we trim the leading comma
-- end of field list
+ ')
WITH (
PAD_INDEX = OFF
);',
/*
** DISABLE index
*/
disable_sql = 'ALTER INDEX ' + x.[index_name] + ' ON ' + x.[owner_name] + '.' + x.[table_name] + ' DISABLE;',
/*
** ENABLE (REBUILD) index
*/
enable_sql = 'ALTER INDEX ' + x.[index_name] + ' ON ' + x.[owner_name] + '.' + x.[table_name] + ' REBUILD;'
FROM
(SELECT
[owner_name] = SCHEMA_NAME(O.schema_id),
[table_name] = O.name,
[index_name] = I.name
-- other interesting, but not used fields that might be useful for other index types:
-- O.type,I.index_id,I.is_unique,
-- prop= INDEXPROPERTY(I.object_id,I.name,'IsClustered'),
-- I.is_padded,
-- I.fill_factor,
-- I.ignore_dup_key,I.allow_row_locks,I.allow_page_locks,I.is_disabled,I.data_space_id
FROM
sys.all_objects O INNER JOIN sys.indexes I on O.object_id=I.object_id
WHERE
I.index_id>0
-- AND O.name = @target_table_name
AND O.type <> 'IT'
AND INDEXPROPERTY(I.object_id,I.name,'IsStatistics') <> 1
AND INDEXPROPERTY(I.object_id,I.name,'IsAutoStatistics') <> 1
AND INDEXPROPERTY(I.object_id,I.name,'IsHypothetical') <> 1
AND I.is_primary_key = 0
AND I.is_unique_constraint = 0
) as x
最も基本的なインデックスのみが再作成されますが、必要に応じてより複雑なインデックスを作成するための基礎として役立ついくつかの追加フィールドを残しました。
コマンドはビューの各フィールドにあります。execを使用して、実際に次のような操作を実行します ( のテーブル名を入力します@target_table_name
)。
Declare @target_table_name as sysname = 'mytable';
Declare @sql_cmd as table(ID int identity, cmd varchar(max) );
Declare @this_cmd as varchar(max) = '';
Declare @ct as int = 0;
-- populate a temp table to store the results
INSERT INTO @sql_cmd(cmd)
SELECT
cmd = enable_sql
FROM
dbo.vw_INDEX_TEXT
WHERE
table_name = @target_table_name
-- the ID column will help us step though the rows one at a time
SELECT @ct = max(ID) FROM @sql_cmd
-- loop over all rows in the table, finding each individual command
While (@ct > 0) Begin
SELECT
@this_cmd = cmd
FROM
@sql_cmd
WHERE
id = @ct
select @this_cmd
-- un-comment this line to actually run the command:
-- exec (@this_cmd)
SET @ct = @ct - 1
End
exec
この例では が無効になっていることに注意してください。