我们正在运行 SQL Server 2012 标准版。
需要更改具有 +100M 行的表中的列名。
该表一直被大量使用。
我现在不能说有问题的列是否是索引的一部分(如果是,我应该期待不同的行为吗?)
运行时我应该期望的性能影响是什么:
EXEC sp_rename 'myTable.oldColumnName', 'newColumnName','COLUMN'
Run Code Online (Sandbox Code Playgroud)
编辑:此列是为将来的需要而创建的,我们知道它没有用于系统的任何部分。它只有空值。我现在离线,不确定它是否包含在索引中(错误地)
编辑 2:此表上的大多数事务都有 with(nolock) 提示。您认为在隔离杆读取未提交时运行 sp_rename 是要走的路吗?
桌子的大小无关紧要。更改列名只会更改表中的元数据。但是,SQL Server 中没有列元数据锁的概念。重命名列需要表上的模式修改锁。以下是锁定请求的样子:
<Database name="TEST">
<Locks>
<Lock request_mode="S" request_status="GRANT" request_count="1" />
</Locks>
<Objects>
<Object name="rename_col_test" schema_name="dbo">
<Locks>
<Lock resource_type="OBJECT" request_mode="Sch-M" request_status="WAIT" request_count="1" />
</Locks>
</Object>
</Objects>
</Database>
Run Code Online (Sandbox Code Playgroud)
在默认隔离级别下,在您发出重命名后,它将被任何已经在该对象上使用任何类型的锁运行的查询阻止。在您的重命名请求之后启动的任何需要锁定表的查询都将被重命名阻止。
下面是一个如何形成阻塞链的例子:
会话 52 是一个长时间运行SELECT,持有表上的锁。会话 53 尝试重命名表。会话 54 是另一个SELECT与会话 52 使用的锁兼容的查询,但它被重命名阻止。