Sqlserver修改線上表的表欄位型別
原本很多欄位都是nvarchar型別,因為nvarchar型別的欄位無法新增索引,所以要線上把表的欄位型別修改為varchar。
執行指令碼如下:
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_events
(
id int NOT NULL IDENTITY (1, 1),
transaction_id varchar(255) NULL,
trans_no varchar(255) NULL,
broker varchar(32) NULL,
code varchar(100) NULL,
consumer_id varchar(255) NULL,
consumer_code varchar(100) NULL,
consumer_name nvarchar(255) NULL,
description varchar(100) NULL,
comment nvarchar(255) NULL,
execution_group varchar(50) NULL,
input_ts bigint NOT NULL,
output_ts bigint NOT NULL,
provider_id varchar(100) NULL,
provider_code varchar(50) NULL,
provider_name nvarchar(255) NULL,
request_body nvarchar(MAX) NULL,
request_header nvarchar(MAX) NULL,
request_ts bigint NOT NULL,
response_body nvarchar(MAX) NULL,
response_header nvarchar(MAX) NULL,
response_ts bigint NOT NULL,
service_id varchar(50) NULL,
service_code varchar(50) NULL,
service_name nvarchar(255) NULL,
service_version varchar(50) NULL,
service_url varchar(255) NULL,
category_name varchar(50) NULL,
source varchar(50) NULL,
type varchar(50) NULL
) ON [PRIMARY]
TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_events SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_events ON
GO
IF EXISTS(SELECT * FROM dbo.events)
EXEC('INSERT INTO dbo.Tmp_events (id, transaction_id, trans_no, broker, code, consumer_id, consumer_code, consumer_name, description, comment, execution_group, input_ts, output_ts, provider_id, provider_code, provider_name, request_body, request_header, request_ts, response_body, response_header, response_ts, service_id, service_code, service_name, service_version, service_url, category_name, source, type)
SELECT id, CONVERT(varchar(255), transaction_id), CONVERT(varchar(255), trans_no), CONVERT(varchar(32), broker), CONVERT(varchar(100), code), CONVERT(varchar(255), consumer_id), CONVERT(varchar(100), consumer_code), CONVERT(nvarchar(255), consumer_name), CONVERT(varchar(100), description), CONVERT(nvarchar(255), comment), CONVERT(varchar(50), execution_group), input_ts, output_ts, CONVERT(varchar(100), provider_id), CONVERT(varchar(50), provider_code), CONVERT(nvarchar(255), provider_name), request_body, request_header, request_ts, response_body, response_header, response_ts, CONVERT(varchar(50), service_id), CONVERT(varchar(50), service_code), CONVERT(nvarchar(255), service_name), CONVERT(varchar(50), service_version), CONVERT(varchar(255), service_url), CONVERT(varchar(50), category_name), CONVERT(varchar(50), source), CONVERT(varchar(50), type) FROM dbo.events WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_events OFF
GO
DROP TABLE dbo.events
GO
EXECUTE sp_rename N'dbo.Tmp_events', N'events', 'OBJECT'
GO
ALTER TABLE dbo.events ADD CONSTRAINT
PK__esb_even__3213E83FA9B6FB29 PRIMARY KEY CLUSTERED
(
id
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT
可以看出,sqlserver進行修改表欄位型別其實就是建立一個新表,把老表的資料轉換型別後插入到新表,然後drop掉老表。
再對新表的欄位新增索引即可。
因為整個過程是在一個事務中進行的,所以會鎖表。
測試下來。
在非業務繁忙期的一個線上表369W條左右的資料量,整個線上修改表欄位型別消耗了14分32秒。
執行指令碼如下:
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_events
(
id int NOT NULL IDENTITY (1, 1),
transaction_id varchar(255) NULL,
trans_no varchar(255) NULL,
broker varchar(32) NULL,
code varchar(100) NULL,
consumer_id varchar(255) NULL,
consumer_code varchar(100) NULL,
consumer_name nvarchar(255) NULL,
description varchar(100) NULL,
comment nvarchar(255) NULL,
execution_group varchar(50) NULL,
input_ts bigint NOT NULL,
output_ts bigint NOT NULL,
provider_id varchar(100) NULL,
provider_code varchar(50) NULL,
provider_name nvarchar(255) NULL,
request_body nvarchar(MAX) NULL,
request_header nvarchar(MAX) NULL,
request_ts bigint NOT NULL,
response_body nvarchar(MAX) NULL,
response_header nvarchar(MAX) NULL,
response_ts bigint NOT NULL,
service_id varchar(50) NULL,
service_code varchar(50) NULL,
service_name nvarchar(255) NULL,
service_version varchar(50) NULL,
service_url varchar(255) NULL,
category_name varchar(50) NULL,
source varchar(50) NULL,
type varchar(50) NULL
) ON [PRIMARY]
TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_events SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_events ON
GO
IF EXISTS(SELECT * FROM dbo.events)
EXEC('INSERT INTO dbo.Tmp_events (id, transaction_id, trans_no, broker, code, consumer_id, consumer_code, consumer_name, description, comment, execution_group, input_ts, output_ts, provider_id, provider_code, provider_name, request_body, request_header, request_ts, response_body, response_header, response_ts, service_id, service_code, service_name, service_version, service_url, category_name, source, type)
SELECT id, CONVERT(varchar(255), transaction_id), CONVERT(varchar(255), trans_no), CONVERT(varchar(32), broker), CONVERT(varchar(100), code), CONVERT(varchar(255), consumer_id), CONVERT(varchar(100), consumer_code), CONVERT(nvarchar(255), consumer_name), CONVERT(varchar(100), description), CONVERT(nvarchar(255), comment), CONVERT(varchar(50), execution_group), input_ts, output_ts, CONVERT(varchar(100), provider_id), CONVERT(varchar(50), provider_code), CONVERT(nvarchar(255), provider_name), request_body, request_header, request_ts, response_body, response_header, response_ts, CONVERT(varchar(50), service_id), CONVERT(varchar(50), service_code), CONVERT(nvarchar(255), service_name), CONVERT(varchar(50), service_version), CONVERT(varchar(255), service_url), CONVERT(varchar(50), category_name), CONVERT(varchar(50), source), CONVERT(varchar(50), type) FROM dbo.events WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_events OFF
GO
DROP TABLE dbo.events
GO
EXECUTE sp_rename N'dbo.Tmp_events', N'events', 'OBJECT'
GO
ALTER TABLE dbo.events ADD CONSTRAINT
PK__esb_even__3213E83FA9B6FB29 PRIMARY KEY CLUSTERED
(
id
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT
可以看出,sqlserver進行修改表欄位型別其實就是建立一個新表,把老表的資料轉換型別後插入到新表,然後drop掉老表。
再對新表的欄位新增索引即可。
因為整個過程是在一個事務中進行的,所以會鎖表。
測試下來。
在非業務繁忙期的一個線上表369W條左右的資料量,整個線上修改表欄位型別消耗了14分32秒。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22996654/viewspace-2147690/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 修改表的欄位型別型別
- sqlserver查詢一個庫所有表的欄位名及欄位型別SQLServer型別
- 【轉】修改表的欄位資料型別的方法資料型別
- oracle 修改欄位型別的方法Oracle型別
- sqlite sql 修改欄位型別SQLite型別
- Oracle-不刪表資料,修改欄位型別Oracle型別
- 修改欄位資料型別的方法資料型別
- sql語句修改欄位型別和增加欄位SQL型別
- Oracle 修改欄位型別和長度Oracle型別
- 改變表中非空欄位的型別型別
- mysql表操作(alter)/mysql欄位型別MySql型別
- 含LONG型別欄位的表無法MOVE型別
- oracle的欄位型別Oracle型別
- SQLServer SYSPROCESSES表欄位解說明SQLServer
- 在SQL Server中修改欄位型別和欄位名稱的儲存過程SQLServer型別儲存過程
- mssql sqlserver 可以儲存二進位制資料的欄位型別詳解SQLServer型別
- oracle 修改表欄位的長度Oracle
- 保留兩位小數:資料庫欄位型別NUMBER,Java欄位型別Double型別資料庫型別Java
- OCM實驗-建立含特殊欄位型別的表型別
- sql小筆記(增刪改查——新增列、修改表名、列的欄位型別等)SQL筆記型別
- MongoDB更改欄位型別MongoDB型別
- oracle檢視該使用者的所有表名字、表註釋、欄位名、欄位註釋、是否為空、欄位型別Oracle型別
- MongoDB中的欄位型別IdMongoDB型別
- MySQL欄位新增註釋,但不改變欄位的型別MySql型別
- postgresql分割槽表修改資料表欄位SQL
- mysql修改表、欄位、庫的字符集MySql
- MySQL欄位型別最全解析MySql型別
- date、timestamp欄位型別型別
- MySQL欄位型別小記MySql型別
- 資料欄位型別匹配型別
- [提問交流]建立模型,新增屬性,欄位型別如何設定2位小數的欄位型別模型型別
- SQLServer2012刪除表欄位SQLServer
- mysql修改表欄位學習筆記MySql筆記
- 查詢mysql某張表中的所有資料(欄位)型別MySql型別
- SQL Server複製的表中如何修改欄位SQLServer
- 主流資料庫欄位型別轉.Net型別的方法資料庫型別
- 【mongo】mongo 欄位型別互轉Go型別
- [轉]MySQL 欄位型別參考MySql型別