SQL Server同实例跨库导出MyTable表耗时过长的问题排查求助
问题
使用SQL Server Management Studio在同一服务器的两个数据库间导出数据时,仅含约18000条记录的MyTable表导出耗时数小时(2万+记录的大表耗时反而短很多)。当前单独导出该表,无其他任务运行;已在编辑映射中开启identity insert(其他表此操作正常),复制对话框显示“Executing”“In Progress...”。
建表语句如下:
USE [myDatabase] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[MyTable]( [ID] [int] IDENTITY(1,1) NOT NULL, [errors] [varchar](max) NULL, [timestamp] [datetime] NULL, [productname] [varchar](50) NULL, [product_id] [varchar](10) NULL, CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO
原因分析与解决办法
原因1:varchar(max)字段存储大量数据
errors字段是varchar(max),如果其中多数行存储了长文本(比如完整错误堆栈、大段日志),哪怕总记录数少,实际数据量可能远超那些2万+记录的表。SSMS导出工具默认逐行处理大字段,速度会被拖慢。
解决办法:
- 直接用T-SQL语句迁移,效率比SSMS可视化工具高很多。目标库先建好表,执行以下语句:
-- 开启IDENTITY_INSERT SET IDENTITY_INSERT [目标库名].[dbo].[MyTable] ON; INSERT INTO [目标库名].[dbo].[MyTable] (ID, errors, timestamp, productname, product_id) SELECT ID, errors, timestamp, productname, product_id FROM [源库名].[dbo].[MyTable]; SET IDENTITY_INSERT [目标库名].[dbo].[MyTable] OFF; - 若不需要完整数据,可先过滤
errors字段内容过大的行,单独处理这部分数据。
原因2:表统计信息过期
虽然建表时设置了STATISTICS_NORECOMPUTE = OFF(自动更新统计),但如果表数据有过大规模变更,统计信息可能失效,导致查询优化器选择低效执行计划,拖慢导出速度。
解决办法:
- 更新该表的统计信息:
UPDATE STATISTICS [源库名].[dbo].[MyTable] WITH FULLSCAN; - 更新后再尝试导出,或直接用上述T-SQL语句迁移。
原因3:SSMS导出工具默认设置低效
SSMS导出向导默认采用逐行提交的方式,对于含大字段的表,这种方式会频繁触发IO操作,导致速度极慢。
解决办法:
- 在导出向导的「保存并运行包」页面,点击「高级」按钮,调整参数:
- 调大
CommitSize(提交批次大小),比如设为1000或5000,减少提交次数; - 启用
UseFastLoad选项,使用BULK INSERT方式提升导入速度。
- 调大
原因4:隐性锁或阻塞
即使没有明显的其他任务,仍可能存在未提交的事务、后台维护任务导致的锁等待,拖慢导出进程。
解决办法:
- 打开SSMS活动监视器排查:
- 右键服务器实例 → 活动监视器;
- 在「进程」「等待任务」中筛选目标数据库和
MyTable,确认是否有阻塞进程; - 若有,终止无关的阻塞进程(注意评估业务影响)。
内容的提问来源于stack exchange,提问作者cdub
相关产品推荐
相关产品推荐

