记录一下 exec sp_executesql 执行时间异常 的解决过程
华为笔记本在执行SQL插入操作时出现3秒延迟,原因是网络驱动问题。通过SQL Server Profiler抓取发现,使用sp_executesql执行SQL语句时响应缓慢,而直接执行SQL则正常。经ChatGPT分析,问题可能源于网卡驱动未开启LargeSendOffload功能,导致大数据包处理效率低下。解决方案是更新英特尔官方网卡驱动,替换华为定制驱动后,所有SQL操作均恢复毫秒级响应速度。
事情的起因是这样的:
在测试Winform 应用的过程中,发现自己的电脑操作应用很丝滑。增删改查的操作数据库基本都是毫秒级别的反应。
到另一台华为笔记本(华为MateBook 14)测试却出现了很奇怪的问题,查询操作的响应速度很正常。
但是一旦做有关 Insert 操作时 本来几毫秒能完成的事情,却硬生生转了3秒左右
(数据很少只有几行) 又试了一下 数据达到几十行时保存起码要几十秒!!!
这还怎么玩?
开始排查问题,怀疑跟电脑环境有关系,于是换了另一台笔记本测试,发现没有问题
打开SQL Server Profiler工具 把执行的SQL抓取下来
exec sp_executesql N'insert into SysLog(OperateUser,OperateModule,OperateType,OperateNo,OperateDate,OperateIP,OperateContent,OperateMac) values (@OperateUser,@OperateModule,@OperateType,@OperateNo,@OperateDate,@OperateIP,@OperateContent,@OperateMac) ;select @@IDENTITY'
, N'@OperateUser nvarchar(100),@OperateModule nvarchar(100),@OperateType nvarchar(255),@OperateNo nvarchar(25),@OperateDate datetime,@OperateIP nvarchar(25),@OperateContent nvarchar(max) ,@OperateMac nvarchar(255)'
, @OperateUser = N'administrator'
, @OperateModule = N'Orders'
, @OperateType = N'新增'
, @OperateNo = N'OD2506270001'
, @OperateDate = '2025-06-27 16:44:47.483'
, @OperateIP = N'192.168.1.2'
, @OperateContent = N'{"money":789000,"build_date":"\/Date(1751013887482+0800)\/","build_id":"SysAdmin","check_date":null,"check_id":null,"currency_no":"CNY","cust_id":"1000","deposit":10000,"free_day":0,"is_checked":0,"modify_date":null,"modify_id":null,"orders_date":"\/Date(1750953600000+0800)\/","orders_no":"OD2506270001","orders_type":"2","remark":"测试","sale_id":"请选择","store_prc":10,"prod_id":"01","wgt":1000,"wgt_prc":789}'
, @OperateMac = N'0C:9A:3C:80:8A:FE';
在华为电脑上运行这段SQL 发现执行时间为3秒
尝试不用 sp_executesql 的方式 来执行SQL
INSERT INTO SysLog (
OperateUser,
OperateModule,
OperateType,
OperateNo,
OperateDate,
OperateIP,
OperateContent,
OperateMac
)
VALUES (
N'administrator',
N'Orders',
N'新增',
N'OD2506270001',
'2025-06-27 16:44:47.483',
N'192.168.1.2',
N'{"money":789000,"build_date":"\/Date(1751013887482+0800)\/","build_id":"SysAdmin","check_date":null,"check_id":null,"currency_no":"CNY","cust_id":"1000","deposit":10000,"free_day":0,"is_checked":0,"modify_date":null,"modify_id":null,"orders_date":"\/Date(1750953600000+0800)\/","orders_no":"OD2506270001","orders_type":"2","remark":"测试","sale_id":"请选择","store_prc":10,"prod_id":"01","wgt":1000,"wgt_prc":789}',
N'0C:9A:3C:80:8A:FE'
);
发现居然只要0毫秒 一点问题没得
但是到这里我还是不知道如何解决,如果是第二种用SQL拼接的方式,那系统要大改,所以不太可能采取这种方式,并且其他电脑用sp_executesql 执行并没有问题
所以我开始网上到处求医,各种改配置,改这哪儿的,一点用没有
然后没得办法了,询问伟大的AI大人:ChatGPT
ChatGPT 大人告诉我:
• 原理差异
• 文字 SQL(CommandType=Text)和 sp_executesql(CommandType=StoredProcedure)在 TDS 协议层走的是两种不同的消息类型:
• Text 查询往往被打包成一个较小的单包请求
• sp_executesql 则会把整个执行字符串+参数打成一个更大的 RPC 包
• 为什么会慢
• 这个“大 RPC 包”超过了网络的 MTU,操作系统/网卡要把它 拆分成多个 IP 分片;其他测试机网卡驱动可能打开了 Large Send Offload(大发送卸载),硬件自动做分片合并,但这台 MateBook 的驱动要全都跑到 CPU 上,分片–重组、检查和逐片发送就消耗了几百到上千毫秒。
• 排查 & 解决
1. 抓包比对:用 Wireshark 对比两台机器发 sp_executesql 时的 TCP 报文,看这台是否有大量 Fragment。
2. 网卡高级设置:打开“控制面板→网络适配器→属性→配置→高级”,启用或禁用「Large Send Offload」「TCP Checksum Offload」「Interrupt Moderation」等条目,看哪项开关能瞬间把时间拉回毫秒级。
3. 调整 TDS 包大小:在连接字符串里加入 Packet Size=4096;(或更小),让 sp_executesql 的 RPC 包不超 MTU。
于是乎我按照它的方式去到 网络适配器里找了一遍 发现没有这个选项!(大量发送卸载)
去到华为电脑管家 升级最新的驱动也不行
后边怀疑华为给的网卡驱动版本不太对 可能是定制版本 不是英特尔的官方版本
于是到英特尔的官方网站对比了一下 两边版本号对不上,下载了最新的驱动安装重启
然后再去执行SQL 增删改查 都是毫秒级别的响应,
被这个驱动坑惨了......
更多推荐
所有评论(0)