SQL Server 2012中20亿行varchar转int/bigint的弊端咨询
把SQL Server 2012中11位纯数字varchar列转为bigint/int的弊端分析
首先得给你提个关键前提:11位纯数字已经超出了int类型的范围。int的最大值是2147483647(仅10位),而11位数字最小是10000000000,所以转int一定会触发溢出错误,直接排除int选项,只能考虑bigint。
接下来聊聊转换过程和后续可能遇到的弊端:
数据溢出或转换失败风险:
虽然你说列里是纯数字,但一定要先做严格校验——比如有些行可能藏有空格、制表符或者其他非数字字符(比如导入时的脏数据),用TRY_CAST(your_column AS bigint) IS NULL排查所有行,一旦有不符合的,转换DDL会直接失败,甚至可能导致表在中间状态不可用。就算全是纯数字,转int的话直接就报错,这点务必注意。DDL操作的锁表影响:
更改列类型属于Schema Modification(Sch-M)锁操作,执行期间整个表会被独占锁定。虽然你说当前无人使用,但如果有突发的后台任务、监控查询或者不小心的访问,都会被阻塞;如果锁等待时间过长,操作还可能失败。建议在确定绝对无访问的窗口执行,或者先做表备份。现有依赖代码/查询的兼容性问题:
如果有应用程序、存储过程或者查询依赖这个列的字符串特性,转成数值类型后会直接出问题。比如:- 原来的字符串拼接
your_column + '_suffix'会报错,因为不能把bigint和字符串直接拼接; - 原来的模糊查询
WHERE your_column LIKE '123%',转成bigint后得改成范围查询WHERE your_column BETWEEN 12300000000 AND 12399999999,逻辑完全变了; - 隐式转换导致索引失效:如果后续查询还是用字符串值和这个列比较(比如
WHERE your_column = '12345678901'),SQL Server会把列值隐式转为字符串,这时候你建的数值索引就没法用,反而达不到性能优化的目的。
- 原来的字符串拼接
后续扩展的限制:
如果你之后需要存储超过19位的数字(虽然现在是11位),bigint也会不够用,但这个场景概率很低。不过如果未来有存储带前导零的需求(比如作为标识号),数值类型会自动去掉前导零,丢失原有格式信息——当然你现在是纯数字,这点可能不影响,但还是要提。
给你的建议
- 先做数据校验:运行
SELECT * FROM your_table WHERE TRY_CAST(your_column AS bigint) IS NULL确认没有脏数据; - 备份表:执行
SELECT * INTO your_table_backup FROM your_table,防止转换失败丢数据; - 执行转换DDL:
ALTER TABLE your_table ALTER COLUMN your_column bigint NOT NULL;(如果原来允许NULL,去掉NOT NULL); - 转换完成后再创建索引:
CREATE INDEX IX_your_table_your_column ON your_table(your_column);; - 测试所有依赖该列的应用和查询,确保逻辑正常。
内容的提问来源于stack exchange,提问作者Melih
相关产品推荐
相关产品推荐

