使用动态sql(sp_executesql)删除和创建索引
我有一个场景,我试图在30多个数据库上创建和维护索引,这些数据库定期从备份中恢复 我有以下存储过程:使用动态sql(sp_executesql)删除和创建索引,sql,indexing,sql-server-2012,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) DE
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
这样做很好,可以删除并重新创建索引,但是随着索引的增长,每次迭代的时间越来越长。
如果数据库已经包含适当的索引,是否有任何方法可以将其更改为跳过数据库?
我试着想出一种方法来做这件事,但还是画了一个空白。您已经在检查索引是否存在,如果存在,就删除它。所以只要用IF-ELSE逻辑扩展它就行了
IF EXISTS...
SET @FirstCommand='DROP INDEX...'
ELSE
SET @FirstCommand='CREATE NONCLUSTERED INDEX...'
然后,您只需要为每个索引执行一个sp_executesql(而不是一次拖放和一次创建)。我需要在动态sql中运行
IF EXISTS
,因为我必须指定许多数据库名称中的一个,如何在动态sql中运行它,但保持IF/ELSE结构?不久前我已经尝试过类似的方法,但我得到了一个错误:索引'IX_FIRSTINDEX'在编译动态查询时已经存在?设置@FirstCommand=,如果存在。。。删除索引。。。否则创建非聚集索引…'如果它存在,我不想删除它,我只想创建它,如果它不存在。当然-发布以前的评论太快了。这实际上更简单:设置@FirstCommand=,如果不存在的话。。。创建非聚集索引…“当我再次尝试时,它起作用了,我以前肯定有语法问题,感谢您的时间。