sql-server – 为什么CREATE INDEX … WITH ONLINE = ON会在几分钟内阻止对表的访问?

前端之家收集整理的这篇文章主要介绍了sql-server – 为什么CREATE INDEX … WITH ONLINE = ON会在几分钟内阻止对表的访问?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一张现有的桌子:
CREATE TABLE dbo.ProofDetails
(
    ProofDetailsID int NOT NULL 
        CONSTRAINT PK_ProofDetails 
        PRIMARY KEY CLUSTERED IDENTITY(1,1),ProofID int NULL,IDShownToUser int NULL,UserViewedDetails bit NOT NULL 
        CONSTRAINT DF_ProofDetails_UserViewedDetails 
        DEFAULT ((0))
);

该表有150,000,000行.该系统24x7x365全天候运行,因此没有定期维护的窗口.

我想在表中添加索引,使用sql Server的企业版,我应该能够在不阻止对表的写访问的情况下执行此操作.我使用的命令是:

CREATE INDEX IX_ProofDetails_ProofID_Etc 
ON dbo.ProofDetails (ProofID,IDShownToUser)
INCLUDE (UserViewedDetails)
WITH (ONLINE=ON,ALLOW_ROW_LOCKS=ON,ALLOW_PAGE_LOCKS=ON,FILLFACTOR=100,MAXDOP=4
);

我按下F5,在SSMS中单独执行了该声明.它跑了一分多钟,然后开始阻止其他会话.然后我立即取消了CREATE INDEX命令,因为我无法阻止其他会话.

在第一分钟,没有任何东西阻止我的CREATE INDEX命令,sys.dm_exec_requests显示进程的等待类型为CXPACKET – 当然.我不认为这是一件坏事,因为操作是并行化的.

我没有太多时间来检查sys.dm_exec_requests的输出.从查询WHERE session_id = xxx返回的只有一行.被阻止的会话试图将行插入目标表.

我不知道锁持续了多长时间,只是说我在开始后大约2分钟取消了声明的执行.此时块发生了大约一分钟.

我误解了WITH(ONLINE = ON)的实现吗?或者还有其他我需要注意的事情吗?

该服务器是一台相当强大的机器,具有2个四核Xeon E5-2643 3.3Ghz处理器,192GB RAM和SAN存储,可支持5,000 iops. cpu通常低于20%,RAM使用率为93%,主要由sql Server提供.这个盒子上没有其他东西可以运行,只有Windows Server 2012和sql Server 2012.

解决方法

使用online = on创建索引时,创建索引进程本身不会阻止创建索引进程,但是当它接近进程结束时,它将获取一段时间的模式修改锁*以实际将索引添加到表中,此锁定类型将阻止所有外部操作,直到锁定被释放,这可能会导致阻塞问题.

*在线构建新的非聚簇索引不需要Sch-M锁,但在所有其他情况下都需要.新的非聚簇索引在最后阶段仅需要表级共享锁,与准备阶段期间所需的相同.

有关详情,请参阅此白皮书:

Online Indexing Operations in SQL Server 2005

正如Mushtaq Mohammed在对该问题的评论中所建议的那样,另见:

Unicorns,rainbows,and online index operations by Paul Randal

原文链接:https://www.f2er.com/mssql/80576.html

猜你在找的MsSQL相关文章