使用动态sql删除和创建索引(sp_executesql)

时间:2014-04-29 14:51:09

标签: sql indexing sql-server-2012

我有一个场景,我试图在30多个数据库上创建和维护索引,这些数据库定期从备份中恢复。

我有以下存储过程:

ALTER PROCEDURE Create_Index 
    @DATABASE sysname 

AS
BEGIN

    DECLARE @DROPFIRSTINDEX nvarchar(MAX)
    DECLARE @DROPSECONDINDEX nvarchar(MAX)
    DECLARE @CREATEFIRSTINDEX nvarchar(MAX)
    DECLARE @CREATESECONDINDEX nvarchar(MAX)


    SET @DROPFIRSTINDEX = 

    N'IF  EXISTS (SELECT * FROM ' + QUOTENAME(@DATABASE) + N'.[sys].[indexes] WHERE object_id = OBJECT_ID(N''' + QUOTENAME(@DATABASE) + N'.[dbo].[FirstTable]'') AND name = N''IX_FIRSTINDEX'')
    DROP INDEX [IX_FIRSTINDEX] ON ' + QUOTENAME(@DATABASE) + N'.[dbo].[FirstTable] WITH ( ONLINE = OFF )'

    SET @DROPSECONDINDEX =

    N'IF  EXISTS (SELECT * FROM ' + QUOTENAME(@DATABASE) + N'.[sys].[indexes] WHERE object_id = OBJECT_ID(N''' + QUOTENAME(@DATABASE) + N'.[dbo].[SecondTable]'') AND name = N''IX_SECONDINDEX'')
    DROP INDEX [IX_SECONDINDEX] ON ' + QUOTENAME(@DATABASE) + N'.[dbo].[SecondTable] WITH ( ONLINE = OFF )'

    SET @CREATEFIRSTINDEX = 

    N'CREATE NONCLUSTERED INDEX [IX_FIRSTINDEX] ON ' + QUOTENAME(@DATABASE) + N'.[dbo].[FirstTable] 
    (
        [DateTime] ASC
    )WITH (STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF
         , IGNORE_DUP_KEY = OFF
         , DROP_EXISTING = OFF
         , ONLINE = OFF
         , ALLOW_ROW_LOCKS  = ON
         , ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]'

    SET @CREATESECONDINDEX =

    N'CREATE NONCLUSTERED INDEX [IX_SECONDINDEX]
    ON ' + QUOTENAME(@DATABASE) + N'.[dbo].[SecondTable] ([CustomerID],[SessionID])
    INCLUDE ([Type])'

    EXEC sp_executesql @DROPFIRSTINDEX 

    EXEC sp_executesql @DROPSECONDINDEX 

    EXEC sp_executesql @CREATEFIRSTINDEX 

    EXEC sp_executesql @CREATESECONDINDEX 

    RETURN

END
GO

这样可以正常工作并删除并重新创建索引,但是随着它们的增长,每次迭代都会花费更长的时间。 如果已经包含适当的索引,是否有任何方法可以将其更改为跳过数据库? 我已经尝试过这样做的方法,但是已经画了一个空白。

1 个答案:

答案 0 :(得分:1)

您已经检查索引是否存在,如果存在,则将其删除。所以只需使用IF ELSE逻辑扩展它

IF EXISTS...
   SET @FirstCommand='DROP INDEX...'
ELSE
   SET @FirstCommand='CREATE NONCLUSTERED INDEX...'

然后你只需要为每个索引做一个sp_executesql(而不是一个drop和一个create)。