C# · 12月 25, 2021

c# – SQL性能,.Net优化与最佳实践

我需要你的专业人士/大师的确认/解释,以下是因为我的团队告诉我“没关系”,这是我的烦恼:)

背景:我们的主要MVC3 / .Net4网络应用程序正在使用sql Server 2008.我们在任何时候都有约200个并发用户.服务器受到极大的打击(锁定,超时,整体缓慢),我正在尝试应用我在职业生涯中学到的东西,以及我最后一次的MS认证课程.他们是我们所有的事情(“关闭sql连接STAT”),我正在向我的团队解释,这些“小事情”虽然没有一个人有所作为,但最终加起来.

我需要知道以下内容是否具有性能影响,或者只是“最佳实践”

1.使用“USING”关键字.
他们的代码大部分是这样的:

public string SomeMethod(string x,string y) { SomethingDataContext dc = new SomethingDataContext(); var x = dc.StoredProcedure(x,y);}

当我试图告诉他们,使用关闭/释放更快的资源:

using (SomethingDataContext dc = new SomethingDataContext()) { var x = dc.StoredProcedure(x,y);}

他们的观点是GC执行代码完成后,清理完毕,所以使用没有太大的影响.真或假,为什么?

连接池

我总是听说设置连接池可以显着加速任何网站(至少.Net w / MSsql).
我建议我们将以下内容添加到web.config中的连接字符串中:

…”Pooling=True;Min Pool Size=3;Max Pool Size=100;Connection
Timeout=10;”…

他们的论据是.Net / MSsql已经在幕后设置了连接池,并没有必要放入我们的web.config中.对或错?为什么每个其他网站说如果已经设置了最佳性能,应该添加pooling?

3.最小化对DB的调用次数

默认的.Net MVC项目附带的角色/会员资格提供程序是很好的 – 它很方便,并为您做大部分的工作.但是,这些人正在严重使用UsersInRoles(),并且像全局变量一样自由使用它(每次调用该方法都会触发DB).
我创建了一个“用户对象”,用于在每个页面加载上加载所有角色(以及一些其他用户的东西,如GUID等),然后查询该对象,如果用户具有“角色”.

网站的其他部分具有循环超过200次的FOR语句,并在每次pass =超过4000个数据库调用时执行20-30个SQL查询.它以某种方式在几秒钟内完成,但我想要做的是将20-30个DB调用整合成一个,这样就可以一次调用200次(每个循环).
但是,由于sql分析器表示该查询花费了“0秒”,因此它们的参数是如此之快,服务器可以处理这些大量的数据库查询.

我的想法是“是的,这些查询运行速度很快,但是它们正在杀死整个sql服务器的性能.”
这可能是一个促成因素吗?我不担心什么,还是这是服务器整体性能问题的重要因素?

4.其他代码优化

第一个想到的是使用StringBuilder和一个简单的字符串变量.我明白为什么我应该使用StringBuilder(特别是在循环中),但是他们说没关系 – 即使他们需要写10k行,他们的论据是性能提升并不重要.

所有这一切,都是我们学习和钻研的(“最小化范围”)只是“最佳实践”,没有真正的性能增益,或者它们是否都有助于实际/可衡量的性能损失?

编辑***
谢谢你们所有的答案!我有一个基于你的答案的新的(5)问题:
他们实际上并没有使用“使用”,那是什么意思呢?如果连接池自动发生,是否绑定池中的连接,直到GC出现?是否可能每个打开连接到sql服务器增加了一点负担的服务器和减缓?

根据您的建议,我计划对连接时间进行一些严格的基准测试/日志记录,因为我怀疑a)服务器速度较慢,b)它们没有关闭连接,并且c)Profiler在0秒内运行缓慢可能来自连接.

我非常感谢你们的帮助.再次感谢

解决方法 分支代码,使您的更改&基准配置文件针对当前的代码库.那么你会有一些证据来备份你的索赔.

至于你的问题,这里是:

>您应该始终手动处理实现IDisposable的类,GC不会实际调用dispose,但是如果该类也实现了一个finalizer,那么它将在大多数实现中调用finalizer,而只会清除非托管资源.>这是真的.NET框架已经做连接池,我不知道什么是默认值,但连接字符串值只是在那里,以允许你改变它们.> sql语句的执行时间只是故事的一部分,在sql分析器中,您将看到数据库引擎执行查询的时间长短,您缺少的是Web服务器连接所需的时间从数据库服务器接收结果,以便查询可能很快,可以节省大量的IO&网络延迟通过批处理查询.>这是一个很好的做一些分析,以证明连接在字符串构建器上使用的额外的内存.