当前位置: 首页 > 编程语言 > C#

SQL代码比C#代码快吗?分享

时间:2023-04-10 11:20:00 C#

SQL代码比C#代码快吗?几个月前我开始在这家编程公司工作。他们使用的一种做法是尽可能多地使用SQL而不是C#来完成工作。所以,假设我有一个写一些文件列表的简单例子:像这样:stringSQL=@"SELECTf.FileID,f.FileName,f.FileExtension,'/files/'+CAST(u.UserGuidASVARCHAR(MAX))+'/'+(f.FileName+f.FileExtension)ASFileSrc,FileSize=CASEWHENf.FileSizeB<1048576THENCAST(CAST((f.FileSizeB/1024)ASDECIMAL(6,2))ASVARCHAR(8))+'KB'ELSECAST(CAST((f.FileSizeB/1048576)ASDECIMAL(6,2))ASVARCHAR(8))+'MB'ENDFROMFilesfINNERJOINUsersuONf.UserID=u.UserID";//写结果的一些循环{//write...//}比这样的东西更快或更好:stringSQL=@"SELECTu.UserGuid,f.FileID,f.FileName,f.FileExtension,f.FileSizeBFROMFilesfINNERJOINUsersuONf.UserID=u.UserID";//一些用于写入结果的循环{stringFileSrc="/Files/"+result["UserGuid"]+"/"+result["FileName"]+result["FileExtension"];字符串FileSize=ConvertToKbOrMb(结果["FileSizeB"]);//write...//}这个特定的代码并不重要(这只是一些基本的例子)...问题是关于这种事情的一般...加载SQL还是“普通”代码更好?这只是一种糟糕的编程习惯您应该分离和隔离程序的不同部分以供以后维护(想想下一个程序员!)性能许多解决方案的DB性能很差,因此大多数开发人员通常限制SQL数据库访问尽可能小的事务。理想情况下,原始数据到人类可读形式的转换应该发生在最后一点。此外,未格式化数据的内存使用量要小得多,虽然内存很便宜,但您不应该浪费它。缓冲、缓存和传输的每个额外字节都需要时间并减少可用的服务器资源。例如,对于Web应用程序,格式化应该由JSON数据包中的原生JavaScript模板完成。这减少了后端SQL数据库和应用服务器的工作量,减少了需要通过网络传输的数据,所有这些都加快了服务器性能。格式化和本地化。许多解决方案对同一笔交易有不同的输出要求,例如不同的视图,不同的本地化等。通过将格式嵌入到SQL事务中,您将不得不为每个本地化创建一个新事务,这将成为维护噩梦格式化事务也不能用于API接口,您需要另一组事务API接口,它不是使用c#格式化的,你应该使用经过良好测试的模板或字符串处理库,或者至少使用string.Format(),不要在字符串中使用'+'运算符,它很慢并且分担了大多数解决方案都有多个客户端和一个数据库,因此客户端格式化负载由多个客户端CPU共享,而不是单个SQL数据库CPU我严重怀疑SQL比c#快,您应该执行一个简单的基准测试并在此处发布结果:-)第二部分可能有点慢的原因是因为您需要从SQL服务器提取数据并将其提供给代码的C#部分,这需要更多时间。您使用ConvertToKbOrMb(result["FileSizeB"])读取的次数总是会花费更多时间,并且还取决于您的DAL层。我见过一些非常慢的DAL。如果你把它们留在SQLServer上,你会得到额外的处理来获取数据,仅此而已。我根据经验进行的优化之一是始终只提取您需要的数据——您从sqlserver读取的数据越多并将其移动到任何地方(asp.net、控制台、c#程序等),您花在周围的时间就越少它们,特别是如果它们是大字符串,或者进行大量从字符串到数字的转换。回答和直接问题,什么更快-我说你无法比较它们。如果您编写好的代码和好的查询,它们都会尽可能快。SQLServer还保留了大量统计信息并改进了返回查询——c#没有这部分,那有什么可比较的呢?我自己做了一个测试好的,我有很多项目的数据在这里做了一个快速测试,实际上不能证明这个比另一个更快。我办了两个案子。从[dbo].[ARL_Mesur]中选择前100%cI1、cI2、cI3WITH(NOLOCK)WHERE[dbo].[ARL_Mesur].[cWhen]>@cWhen0;foreach(varEnaincAllOfThem){//这是我在SQLServer中移动以查看速度变化的行varresults=Ena.CI1+Ena.CI2+Ena.CI3;sbRender.Append(结果);sbRender.Append(Ena.CI2);sbRender.Append(Ena.CI3);}VSSELECTTOP100PERCENT(cI1+cI2+cI3)ascI1,cI2,cI3FROM[dbo].[ARL_Mesur]WITH(NOLOCK)WHERE[dbo].[ARL_Mesur].[cWhen]>@cWhen0;foreach(varEnaincAllOfThem){sbRender.Append(Ena.CI1);sbRender.Append(Ena.CI2);sbRender.Append(Ena.CI3);事实证明速度接近相同。-所有参数都是双重的-读取已优化,我根本没有额外的读取,只是将处理从一个部分移动到另一个部分。在第165,766行,有一些结果:Start0ms+0msc#processing2005ms+2005mssqlprocessing4011ms+2006msStart0ms+0msc#processing2247ms+2247mssqlprocessing4514ms+2267msStart0ms+0msc#processingStart2018ms+2018ms+2948msc#processing0ms+0msc#processing2043ms+2043mssqlprocessing4133ms+2090ms所以速度会受到很多因素的影响...我们不知道你们公司的问题是什么导致c#比sql处理慢。作为一般经验法则:SQL用于操作数据,而不是格式化数据的显示方式。在SQL中做尽可能多的事情,是的,但只要它服务于该目标。纯粹出于这个原因,我会仔细看看您的“SQL示例”。您的“C#示例”对我来说更像是职责分离。话虽这么说,但请不要走得太远,停止在SQL中做应该在SQL中完成的事情,比如过滤和连接。例如,重新实现INNERJOINUsersuONf.UserID=u.UserID在C#中将是一场灾难,性能方面。至于在这种特殊情况下的性能:我希望“C#示例”(不是所有C#,只是这个示例)会更快一些,因为...f.FileSizeB...似乎比...'/files/'+CAST(u.UserGuidASVARCHAR(MAX))+'/'+(f.FileName+f.FileExtension)ASFileSrc,FileSize=CASEWHENf.FileSizeB...应该节省一些网络带宽。而网络带宽往往比CPU(尤其是客户端CPU)更稀缺。当然,您的里程可能会有所不同,但无论哪种方式,性能差异可能都足够小,以至于其他问题(例如代码的整体可维护性)变得相对更加重要。坦率地说,在这方面,您的“C#示例”对我来说看起来更好。有充分的理由在数据库服务器上做尽可能多的事情。尽量减少必须来回传递的数据量并为服务器提供优化流程的余地是一件好事。但是,您的示例中并未真正说明这一点。这两个进程来回传递尽可能多的数据(第一次可能更多),唯一的区别是谁做计算,可能客户端做得更好。您的问题是关于字符串操作应该在C#还是SQL中完成。我认为这个例子太小了,任何性能提升——单向或其他方式——都是无关紧要的。问题是“应该在哪里完成”?如果代码是作为应用程序一部分的“一次性”代码,那么在应用程序级别执行此操作非常有意义。如果此代码在整个应用程序中重复出现,那么您需要对其进行封装。我认为最好的封装方法是使用SQLServer计算列、视图、表值函数或标量函数(在这种情况下,计算列更可取)。这样可以保证无论在哪里调用,同样的处理都是一样的。在性能方面,数据库代码和C#代码之间存在关键差异。数据库代码自动并行运行。因此,如果您的数据库服务器是多线程的,则单独的线程可能会同时执行这些字符串操作(没有承诺,这里的关键词是“可能”)。通常,在考虑拆分时,您希望尽量减少来回传递的数据量。这种情况下的差异似乎很小。因此,如果应用程序中只有一个地方具有此逻辑,请在应用程序中执行此操作。如果您的应用程序填充对需要此逻辑的此表的引用,请考虑计算列。如果应用程序在不同的表上有许多类似的请求,那么请考虑使用标量值函数,尽管这可能会影响查询利用并行性的能力。这真的取决于你在做什么。不要忘记SQLCLR。有很多操作,T-SQL代码比较慢。通常在生产环境中,数据库基础设施层是应用程序层的两倍,有时是三倍。此外,对于针对数据库本地运行的SQL代码,在应用程序上运行并通过数据库驱动程序传递的SQL代码将具有强大的优势。以上就是C#学习教程:SQL代码比C#代码快吗?如果分享的所有内容对您有用,需要了解更多C#学习教程,希望您多多关注---本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: