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.
解决方法
*在线构建新的非聚簇索引不需要Sch-M锁,但在所有其他情况下都需要.新的非聚簇索引在最后阶段仅需要表级共享锁,与准备阶段期间所需的相同.
有关详情,请参阅此白皮书:
Online Indexing Operations in SQL Server 2005
正如Mushtaq Mohammed在对该问题的评论中所建议的那样,另见:
Unicorns,rainbows,and online index operations by Paul Randal