Azure-Sql-Database
將 nvarchar (4000) 更改為 nvarchar(500)
我有一個性能問題
nvarchar(4000)
。我想根據以下語句更改表格:BEGIN declare @length as int SELECT @length = MAX(LEN([SourceId])) from [dbo].[table] if @length < 500 begin ALTER TABLE [dbo].[table] ALTER COLUMN [SourceId] NVARCHAR(500) NOT NULL; end else select ' column Length greater than 500' as tb end
它會影響數據或索引嗎?我們在表中有超過 1000 萬行。
我首先要提醒您,將來最大長度為 500 的可能性太小。
也就是說,您的程式碼將起作用,儘管它會在表上獲取模式修改鎖,並且如果任何索引引用該列,則無法執行。
這是一篇關於模式修改鎖可能發生的一些問題的優秀文章:Michael J Swart的 Sch-M 鎖是邪惡的。
理想情況下,您在維護視窗中執行此操作,此時沒有事務處理表並且您有一些時間來處理它。
以下是一些範常式式碼,您可以使用它們來了解所涉及的時間:
/* Create Table */ DROP TABLE IF EXISTS dbo._Test CREATE TABLE dbo._Test ( ID INT IDENTITY (1,1) NOT NULL CONSTRAINT PK__TEST PRIMARY KEY CLUSTERED, SourceID NVARCHAR(4000) NOT NULL ) /* Optional Index */ CREATE NONCLUSTERED INDEX SourceID ON dbo._Test (SourceID) /* Load Table */ INSERT INTO dbo._Test (SourceID) SELECT TOP 10000000 O1.Name FROM sys.objects O1 CROSS JOIN sys.objects O2 /* Attempt ALTER */ ALTER TABLE dbo._Test ALTER COLUMN SourceID NVARCHAR(500) /* Fails Due To Index Depending On Column Msg 5074, Level 16, State 1, Line 26 The index 'SourceID' is dependent on column 'SourceID'. Msg 4922, Level 16, State 9, Line 26 ALTER TABLE ALTER COLUMN SourceID failed because one or more objects access this column. */ /* Drop the index */ DROP INDEX IF EXISTS SourceID ON dbo._Test /* Try Again */ ALTER TABLE dbo._Test ALTER COLUMN SourceID NVARCHAR(500) /* Notice this takes a schema modification lock <Object name="_Test" schema_name="dbo"> <Locks> <Lock resource_type="OBJECT" request_mode="Sch-M" request_status="GRANT" request_count="20" /> </Locks> Total time was ≈ 25 seconds on my test system, then may need to add back any indexes or constraints that were referencing the altered column. */
是的,縮短列長度將涉及重新處理表中的所有行以及可能的索引
https://michaeljswart.com/2013/04/altering-text-columns-only-a-metadata-change/