SQLサーバーで大量にある子テーブルのインデックスをまとめて作成する方法

Higtyのシステムの作り方

まずは部品化ということでストアドにします。


/*-------------------------------------
ChildTable_IndexKey_Create_20251125
-------------------------------------*/
DROP PROCEDURE IF EXISTS dbo.ChildTable_IndexKey_Create_20251125;
GO

CREATE PROCEDURE dbo.ChildTable_IndexKey_Create_20251125
(@ParentSchema sysname = N'dbo'   -- 親テーブルのスキーマ
,@ParentTable  sysname           -- 親テーブル名
)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @sql NVARCHAR(MAX) = N'';
    DECLARE @parentFullName NVARCHAR(512)
        = QUOTENAME(@ParentSchema) + N'.' + QUOTENAME(@ParentTable);

    ;WITH FKCols AS
    (
        SELECT DISTINCT
            SchemaName = OBJECT_SCHEMA_NAME(fkc.parent_object_id),
            TableName  = OBJECT_NAME(fkc.parent_object_id),
            ColumnName = c.name
        FROM sys.foreign_keys fk
        JOIN sys.foreign_key_columns fkc
             ON fk.object_id = fkc.constraint_object_id
        JOIN sys.columns c
             ON c.object_id = fkc.parent_object_id
            AND c.column_id = fkc.parent_column_id
        WHERE fk.referenced_object_id = OBJECT_ID(@parentFullName)
    )
    SELECT @sql = @sql + '
IF NOT EXISTS (
    SELECT 1
    FROM sys.indexes i
    WHERE i.object_id = OBJECT_ID(N''' 
        + QUOTENAME(SchemaName) + N'.' + QUOTENAME(TableName) + N''')
      AND i.name      = N''' + TableName + N'_Ix_' + ColumnName + N'''
)
BEGIN
    CREATE NONCLUSTERED INDEX ' + QUOTENAME(TableName + N'_Ix_' + ColumnName) + N'
    ON ' + QUOTENAME(SchemaName) + N'.' + QUOTENAME(TableName) + N'(' 
         + QUOTENAME(ColumnName) + N');
END
'
    FROM FKCols;

    -- FK が1つもないケースだと @sql は空文字になるが、その場合は何も起きない
    IF (@sql <> N'')
    BEGIN
        EXEC sp_executesql @sql;
    END
END

GO

ストアドを作った後、以下のように利用します。

EXEC ChildTable_IndexKey_Create_20251125 'dbo','Tenant'
GO
EXEC ChildTable_IndexKey_Create_20251125 'dbo','User'
GO