我们一直在尝试在我们的系统中重新索引,在索引期间仍有用户使用数据库。在为某些表做索引时,索引失败,这似乎是由于死锁
我们使用的索引脚本是:
-------- REBUILDING THE INDEXES----------------------
CREATE TABLE #TableIDs (Tablename nvarchar(200),IndexName nvarchar(1000))
--Database to be indexed--
INSERT INTO #TableIDs (Tablename, IndexName)
SELECT a.object_id,name
FROM sys.dm_db_index_physical_stats (DB_ID(N'RAL'), NULL, NULL, NULL, NULL) AS a
JOIN sys.indexes AS b ON a.object_id = b.object_id AND a.index_id = b.index_id
Where avg_fragmentation_in_percent > 20 and name is not null and OBJECT_SCHEMA_NAME(a.object_id) = 'dbo'
And object_name(a.object_id) not in (SELECT
OBJECT_NAME(p.object_id) BlockedObjectName
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id
INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
Where db.name = 'RAL')
declare c cursor for select object_name(Tablename) as Tablename ,IndexName from #TableIDs
declare @TableName varchar(1000)
declare @IndexName varchar(1000)
open c
fetch next from c into @TableName, @IndexName
while @@FETCH_STATUS = 0
BEGIN
if ((SELECT
count(OBJECT_NAME(p.object_id)) BlockedObjectName
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id
INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
Where db.name = 'RALMYT' and OBJECT_NAME(p.object_id) = @TableName) ) = 0
BEGIN
EXEC ('ALTER INDEX ' + @IndexName + ' ON ' + @TableName + ' REBUILD WITH (FILLFACTOR=90,STATISTICS_NORECOMPUTE = OFF,ONLINE=OFF,MAXDOP=8)')
PRINT 'Reindexing ' + @IndexName + ' on ' + @TableName + ' table'
END
fetch next from c into @TableName, @IndexName
End
CLOSE c
DEALLOCATE c
DROP TABLE #TableIDs
Run Code Online (Sandbox Code Playgroud)
请让我知道..... 如何在索引时避免错误或失败
如果要求是在让用户继续工作的同时重建索引,您会发现如果您不能进行在线索引重建(仅在企业版中可用),您会发现这非常具有挑战性,如果不是不可能的话。
实际上只有两种解决方案:
REORGANIZE
而不是REBUILD
-- reorgs 总是在线操作,但可能不如重建那么好,并且相比之下可能运行得更慢。无论如何,我强烈建议使用已经构建和测试过的解决方案,例如Ola Hallengren 的维护脚本,而不是滚动您自己的脚本,它将根据索引的当前碎片状态智能地维护您的索引。索引实际上可能并不需要一直重建。
归档时间: |
|
查看次数: |
196 次 |
最近记录: |