有没有碰到过sqlserver中执行sql比较快,使用ado.net却比较慢的情况

baidu_27549073 2017-07-05 10:02:17
今天使用在sqlserver中直接执行语句需要两秒,但是使用SqlHelper.ExecuteDataset却总是超时
...全文
670 20 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
baidu_27549073 2017-07-06
  • 打赏
  • 举报
回复
引用 11 楼 xdashewan 的回复:
参数尝试加上option(recompile),每次都重编译产生最优执行计划
我使用的是参数化查询,会使用sp_executesql去执行sql,但是不使用参数化查询又会有sql注入问题。只能暂时改一下了
baidu_27549073 2017-07-06
  • 打赏
  • 举报
回复
引用 9 楼 xdashewan 的回复:



直接使用sql是第二种查询计划,但是使用sp_executesql查询计划是第一张图。可以看到使用sp_executesql查询计划,排序占了40%,应该是因为这张表比较大。感觉走远了
xdashewan 2017-07-06
  • 打赏
  • 举报
回复
参数尝试加上option(recompile),每次都重编译产生最优执行计划
baidu_27549073 2017-07-06
  • 打赏
  • 举报
回复
引用 9 楼 xdashewan 的回复:


只显示了这个
xdashewan 2017-07-06
  • 打赏
  • 举报
回复
引用 8 楼 baidu_27549073 的回复:
sp_executesql怎么看执行计划?
一样看,查看方式和一般的sql没什么区别
baidu_27549073 2017-07-06
  • 打赏
  • 举报
回复
引用 5 楼 xdashewan 的回复:
[quote=引用 4 楼 baidu_27549073 的回复:] 执行上面的没有问题,但是使用参数化查询执行下面的却有问题,上面的要2s,下面的要17s
你要学会使用执行计划,观看sql本身很难发现问题[/quote] sp_executesql怎么看执行计划?
baidu_27549073 2017-07-06
  • 打赏
  • 举报
回复
引用 6 楼 hanjun0612 的回复:
已经调试了,是运行sql慢,使用sp_executesql(需要17s)比直接使用sql(只需要2s)慢。 执行sp_executesql时触发了SP:StmtStarting后没有执行SP:StmtCompleted就超时了,直接到RPC:Completed
正怒月神 版主 2017-07-06
  • 打赏
  • 举报
回复
引用 4 楼 baidu_27549073 的回复:
执行上面的没有问题,但是使用参数化查询执行下面的却有问题,上面的要2s,下面的要17s
你要先自己调试,看是后台运行sql慢还是装载datatable慢。
xdashewan 2017-07-06
  • 打赏
  • 举报
回复
引用 4 楼 baidu_27549073 的回复:
执行上面的没有问题,但是使用参数化查询执行下面的却有问题,上面的要2s,下面的要17s
你要学会使用执行计划,观看sql本身很难发现问题
baidu_27549073 2017-07-06
  • 打赏
  • 举报
回复
引用 1 楼 xdashewan 的回复:
引用 2 楼 hanjun0612 的回复:
引用 3 楼 zhouzangood 的回复:
declare @bd datetime ='2017-07-06'
select isnull(sum(b.score),0) as SumScore,c.kindid,c.kindName from [thtreasuredb].[dbo].RecordDrawInfo a with(nolock) left join thtreasuredb.dbo.RecordDrawScore b with(nolock) on a.drawid=b.drawid left join [THPlatformDB].[dbo].[GameKindItemWeb] c with(nolock) on a.kindid=c.kindid where userid in(select userid from thaccountsdb.dbo.accountsinfo with(nolock) where isandroid=0 and nullity=0 and userid not in (select account from [THTreasureDB].dbo.web_serialnumlog where type=7))  and b.inserttime>@bd group by c.kindid,c.kindName

exec sp_executesql N'select isnull(sum(b.score),0) as SumScore,c.kindid,c.kindName from [thtreasuredb].[dbo].RecordDrawInfo a with(nolock) left join thtreasuredb.dbo.RecordDrawScore b with(nolock) on a.drawid=b.drawid left join [THPlatformDB].[dbo].[GameKindItemWeb] c with(nolock) on a.kindid=c.kindid where userid in(select userid from thaccountsdb.dbo.accountsinfo with(nolock) where isandroid=0 and nullity=0 and userid not in (select account from [THTreasureDB].dbo.web_serialnumlog where type=7))  and b.inserttime>@bd group by c.kindid,c.kindName',N'@bd datetime',@bd=N'2017-07-06'
执行上面的没有问题,但是使用参数化查询执行下面的却有问题,上面的要2s,下面的要17s
zhouzangood 2017-07-06
  • 打赏
  • 举报
回复
正怒月神 版主 2017-07-06
  • 打赏
  • 举报
回复
大兄弟,sqlserver中执行sql比较快,使用ado.net却比较慢的情况 本来就是啊。 人家ado.net拿出来东西,然后装载到datatable也消耗时间。 首先你要调试 ,使用sql profile监控 SqlHelper.ExecuteDataset执行的sql语句。 然后调试到你对datatable做了什么。
xdashewan 2017-07-06
  • 打赏
  • 举报
回复
SqlHelper.ExecuteDataset是你自定义的方法吧,另外sqlserver内部执行后会有缓存,所以再次执行相同语句会很快,再者ExecuteDataset如果需要填充数据,那么如果数据量巨大,传输和填充也会消耗一定的时间,最后排除上面所说的问题,那么剩下就是数据库本身问题,索引啊表结构是否合理啊,可以通过执行计划去看问题
加油馒头 2017-07-06
  • 打赏
  • 举报
回复
sqlserver 有个神器 SQL Server Profiler 跟踪你的程序输出的SQL语句是什么,然后复制出来执行 再来查找原因
绿领巾童鞋 2017-07-06
  • 打赏
  • 举报
回复
断点看看 ,是查询数据慢,还是数据拿到后处理的业务慢?
baidu_27549073 2017-07-06
  • 打赏
  • 举报
回复
虽然最后原理我还没找到,但是先说下最后说下我的解决方案,如果有其他人碰到这种问题,可以试一下: 问题: 数据库不知道什么原因:对下面的两句解析不一样,第一个要2s,第二个要18s。
declare @bd datetime ='2017-07-06'
select isnull(sum(b.score),0) as SumScore,a.kindid,c.kindName from [thtreasuredb].[dbo].RecordDrawInfo a with(nolock) left join thtreasuredb.dbo.RecordDrawScore b with(nolock) on a.drawid=b.drawid left join [THPlatformDB].[dbo].[GameKindItemWeb] c with(nolock) on a.kindid=c.kindid where userid in(select userid from thaccountsdb.dbo.accountsinfo with(nolock) where isandroid=0 and nullity=0 and userid not in (select account from [THTreasureDB].dbo.web_serialnumlog where type=7))  and b.inserttime>@bd group by a.kindid,c.kindName
 
select isnull(sum(b.score),0) as SumScore,c.kindid,c.kindName from [thtreasuredb].[dbo].RecordDrawInfo a with(nolock) left join thtreasuredb.dbo.RecordDrawScore b with(nolock) on a.drawid=b.drawid left join [THPlatformDB].[dbo].[GameKindItemWeb] c with(nolock) on a.kindid=c.kindid where userid in(select userid from thaccountsdb.dbo.accountsinfo with(nolock) where isandroid=0 and nullity=0 and userid not in (select account from [THTreasureDB].dbo.web_serialnumlog where type=7)) and b.inserttime>='2017/7/6' group by c.kindid,c.kindName
程序中解决方案是,之前使用参数化查询,是使用 SqlHelper.ExecuteDataset(sql,sqlparameter数组)来进行。 直接使用拼接sql来进行是不行的,因为效率跟上面是一样的,需要拼接成下面的样式:

declare @bd datetime ='2017-07-06'
select isnull(sum(b.score),0) as SumScore,a.kindid,c.kindName from [thtreasuredb].[dbo].RecordDrawInfo a with(nolock) left join thtreasuredb.dbo.RecordDrawScore b with(nolock) on a.drawid=b.drawid left join [THPlatformDB].[dbo].[GameKindItemWeb] c with(nolock) on a.kindid=c.kindid where userid in(select userid from thaccountsdb.dbo.accountsinfo with(nolock) where isandroid=0 and nullity=0 and userid not in (select account from [THTreasureDB].dbo.web_serialnumlog where type=7))  and b.inserttime>@bd group by a.kindid,c.kindName
防止sql注入,是使用的格式强转来实现,比如保证datetime一定能转换为datetime类型。
baidu_27549073 2017-07-06
  • 打赏
  • 举报
回复
引用 14 楼 xdashewan 的回复:
[quote=引用 13 楼 baidu_27549073 的回复:] 我使用的是参数化查询,会使用sp_executesql去执行sql,但是不使用参数化查询又会有sql注入问题。只能暂时改一下了
正是因为你使用了sp_executesql,所以才需要option(recompile),因为sp_executesql的特点之一就是重用执行计划,也就是说前一次的执行计划对你换了个参数后并不一定是最优的,所以每次加了option(recompile)促使每次重新编译生成适合于当次查询的执行计划[/quote] 我测试了一下:option(recompile)可以让我的2S的那句变成18s,但是不能让我的18s的变成2s。 我已经在数据库板块提了问了。http://bbs.csdn.net/topics/392189251
baidu_27549073 2017-07-06
  • 打赏
  • 举报
回复
引用 15 楼 xdashewan 的回复:
如果这个问题很头痛的话,你可以发到sqlserver区,那里有专业的DBA,可能比我分析的更加透彻
好的,谢谢,我也差不多明白了
xdashewan 2017-07-06
  • 打赏
  • 举报
回复
如果这个问题很头痛的话,你可以发到sqlserver区,那里有专业的DBA,可能比我分析的更加透彻
xdashewan 2017-07-06
  • 打赏
  • 举报
回复
引用 13 楼 baidu_27549073 的回复:
我使用的是参数化查询,会使用sp_executesql去执行sql,但是不使用参数化查询又会有sql注入问题。只能暂时改一下了
正是因为你使用了sp_executesql,所以才需要option(recompile),因为sp_executesql的特点之一就是重用执行计划,也就是说前一次的执行计划对你换了个参数后并不一定是最优的,所以每次加了option(recompile)促使每次重新编译生成适合于当次查询的执行计划

62,243

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧