问题描述
第一种StringBuilderstrSql=newStringBuilder();strSql.Append(@"selectGameKeyas[GameKey],max(GameName)as[GameName],COUNT(1)as[TCount],sum(RegInfo.OkMoney)as[TMoney],sum(RegInfo.ClearingMoney)as[ClearingMoney],sum(RegInfo.ReturnMoney)as[ReturnMoney]fromRegInfowherePostTimebetween'"+BeginTime.ToString()+"'and'"+EndTime.ToString()+"'");strSql.Append(@"groupbyRegInfo.GameKeyorderbyRegInfo.GameKey");第二种StringBuilderstrSql=newStringBuilder();strSql.Append(@"selectGameKeyas[GameKey],max(GameName)as[GameName],COUNT(1)as[TCount],sum(RegInfo.OkMoney)as[TMoney],sum(RegInfo.ClearingMoney)as[ClearingMoney],sum(RegInfo.ReturnMoney)as[ReturnMoney]fromRegInfo");strSql.Append("wherePostTimebetween@BeginTimeand@EndTime");SqlParameter[]parameters={newSqlParameter("@BeginTime",SqlDbType.DateTime),newSqlParameter("@EndTime",SqlDbType.DateTime)}居然第二种执行出来超时,但在查询分析器里执行出来效率却是一样的,都在1秒多(这个表里有3百多万条数据).而且,第二种方法我不加PostTime也可以成功执行。我想有可能是DateTime的原因,但不知道怎么解决。
解决方案
解决方案二:
1、貌似两句sql不一样,后者缺少group2、如果一样,查询分析器是一样的,因为只是分析语句,加参不加参,对性能影响不大,除非太多
解决方案三:
SqlDbType.DateTime这是日期格式BeginTime.ToString是字符串形式你这两个结果一样吗?
解决方案四:
引用1楼jiuhexuan的回复:
1、貌似两句sql不一样,后者缺少group2、如果一样,查询分析器是一样的,因为只是分析语句,加参不加参,对性能影响不大,除非太多
1."后者缺少group"是因为我复制上来的时候少复制了一句,两句SQL都加了groupby的。2.参数查询只加了一个日期,没加其它的了。通过跟踪出来的语句,然后在查询分析器里执行,效率都是一样的,但就是通过c#程序执行的时候,第二种写法报错(超时)。
解决方案五:
引用2楼bdmh的回复:
SqlDbType.DateTime这是日期格式BeginTime.ToString是字符串形式你这两个结果一样吗?
publicDataSetGetRegInfoGameList(DateTimeBeginTime,DateTimeEndTime)传入参数的类型肯定是一样的。你所说的两个类型肯定是不一样的,不是都推荐用SqlParameter来写吗?如果可以用字符串拼接的方式来写,我不这么头痛了。对了,我的环境是Win7(64位操作系统),VS2010(.net4.0)+SQL2008
解决方案六:
这两个怎么能扯到一块呢
解决方案七:
唉!我终于有点明白了,交流会上老大说过的话:“中国硬编码的人太多了”
解决方案八:
引用5楼hualilihua的回复:
这两个怎么能扯到一块呢
这个是因为在项目中,有遇到的,开始是使用的SqlParameter来写,但报超时错误,就改成字符串拼接,居然正常了,觉得比较神奇,就上现问一下高手们是怎么回事了,为什么SqlParameter还不如字符串拼接效率高?
解决方案九:
引用6楼hualilihua的回复:
唉!我终于有点明白了,交流会上老大说过的话:“中国硬编码的人太多了”
不明白兄弟,您的意思,请明示。
解决方案十:
估计你数据库里面PostTime字段是不是smalldatetime类型?
解决方案十一:
引用6楼hualilihua的回复:
唉!我终于有点明白了,交流会上老大说过的话:“中国硬编码的人太多了”
实在不明白,您这句话,和我这个代码错误有什么关联。
解决方案十二:
引用9楼jiangshun的回复:
估计你数据库里面PostTime字段是不是smalldatetime类型?
谢谢,jiangshun的回复,我开始也以为是和数据库里字段类型不匹配,核对了三次,确实是datetime长度为8位的那种,也不是datetime2(7).
解决方案十三:
StringBuilderstrSql=newStringBuilder();strSql.Append(@"selectGameKeyas[GameKey],max(GameName)as[GameName],COUNT(1)as[TCount],sum(RegInfo.OkMoney)as[TMoney],sum(RegInfo.ClearingMoney)as[ClearingMoney],sum(RegInfo.ReturnMoney)as[ReturnMoney]fromRegInfo");strSql.Append("wherePostTimebetween@BeginTimeand@EndTime");SqlParameter[]parameters={newSqlParameter("@BeginTime",SqlDbType.DateTime),newSqlParameter("@EndTime",SqlDbType.DateTime)}}//没有看到参数的值啥的
lz把代码贴全了瞧瞧
解决方案十四:
引用7楼x2670316290的回复:
引用5楼hualilihua的回复:这两个怎么能扯到一块呢这个是因为在项目中,有遇到的,开始是使用的SqlParameter来写,但报超时错误,就改成字符串拼接,居然正常了,觉得比较神奇,就上现问一下高手们是怎么回事了,为什么SqlParameter还不如字符串拼接效率高?
两个效率没有高低的说法,我估计是你数据库里面的字段类型和声明参数的时候字段类型不一样比如数据库是varchar类型的在SqlParameter(stringparameterName,objectvalue)时候,没有指明具体的类型,所以,默认的就成了nvarchar类型的,在数据量过KW的时候就会出现和varchar类型速度上的区别
解决方案十五:
引用12楼yanbuodiao的回复:
C#codeStringBuilderstrSql=newStringBuilder();strSql.Append(@"selectGameKeyas[GameKey],max(GameName)as[GameName],COUNT(1)as[TCount],sum(RegInfo.OkMoney)as[TMoney],sum(RegInfo.……
或者你在指定值的时候先把那俩字串转成DataTime类型的试试不应该有这种问题的
解决方案:
引用12楼yanbuodiao的回复:
C#codeStringBuilderstrSql=newStringBuilder();strSql.Append(@"selectGameKeyas[GameKey],max(GameName)as[GameName],COUNT(1)as[TCount],sum(RegInfo.OkMoney)as[TMoney],sum(RegInfo.Clear……
publicDataSetGetRegInfoGameList(DateTimeBeginTime,DateTimeEndTime){//#region用字符串拼接测试结果,这个正常//StringBuilderstrSql=newStringBuilder();//strSql.Append(@"//selectGameKeyas[GameKey],max(GameName)as[GameName],COUNT(1)as[TCount],//sum(RegInfo.OkMoney)as[TMoney],sum(RegInfo.ClearingMoney)as[ClearingMoney],sum(RegInfo.ReturnMoney)as[ReturnMoney]//fromRegInfo");//strSql.Append("wherePostTimebetween'"+BeginTime.ToString()+"'and'"+EndTime.ToString()+"'");//returnDbHelperSQL.Query(strSql.ToString());//#endregion#region用SqlParameter测试测试结果,这个报超时错误,但放在查询分析器里不报超时StringBuilderstrSql=newStringBuilder();strSql.Append(@"selectGameKeyas[GameKey],max(GameName)as[GameName],COUNT(1)as[TCount],sum(RegInfo.OkMoney)as[TMoney],sum(RegInfo.ClearingMoney)as[ClearingMoney],sum(RegInfo.ReturnMoney)as[ReturnMoney]fromRegInfo");strSql.Append("wherePostTimebetween@BeginTimeand@EndTime");SqlParameter[]parameters={newSqlParameter("@BeginTime",SqlDbType.DateTime),newSqlParameter("@EndTime",SqlDbType.DateTime)};parameters[0].Value=BeginTime;parameters[1].Value=EndTime;returnDbHelperSQL.Query(strSql.ToString(),parameters);#endregion}
解决方案:
引用13楼jiangshun的回复:
引用7楼x2670316290的回复:引用5楼hualilihua的回复:这两个怎么能扯到一块呢这个是因为在项目中,有遇到的,开始是使用的SqlParameter来写,但报超时错误,就改成字符串拼接,居然正常了,觉得比较神奇,就上现问一下高手们是怎么回事了,为什么SqlParameter还不如字符串拼接效率高?两个效率没有高低的说法……
我确认过三次,刚才又确认了一次,确实是datetime类型。
解决方案:
引用14楼yanbuodiao的回复:
引用12楼yanbuodiao的回复:C#codeStringBuilderstrSql=newStringBuilder();strSql.Append(@"selectGameKeyas[GameKey],max(GameName)as[GameName],COUNT(1)as[TCount],sum(RegInfo.OkMoney……
我也觉得不应该有这种问题,我上面把代码发出来了,传过来的值,确认是datetime类型的
解决方案:
newSqlParameter("@BeginTime",SqlDbType.DateTime),你只是指定了传值的类型是SqlDbType.DateTime型。但是没有传值啊。
解决方案:
publicSqlParameter(stringparameterName,objectvalue)publicSqlParameter(stringparameterName,SqlDbTypedbType)这两个方法是根据传值不同有区别的。个人感觉是这个原因。
解决方案:
引用18楼agilesoftstudio的回复:
newSqlParameter("@BeginTime",SqlDbType.DateTime),你只是指定了传值的类型是SqlDbType.DateTime型。但是没有传值啊。
我再开个贴子吧,这里可能有的朋友没看到我后面发的代码。
解决方案:
明显就是传参类型和数据库中字段的实际类型不一致导致的
解决方案:
引用8楼x2670316290的回复:
引用6楼hualilihua的回复:唉!我终于有点明白了,交流会上老大说过的话:“中国硬编码的人太多了”不明白兄弟,您的意思,请明示。
发错啦不好意思lz不要有意见呀
解决方案:
引用21楼xfreyes的回复:
明显就是传参类型和数据库中字段的实际类型不一致导致的
我确认了已四次了
解决方案:
parameters[0].Value=BeginTime;parameters[1].Value=EndTime;//这里的BeginTime和EndTime是啥类型的?先强转成DateTime类型的试试个人猜测的
解决方案:
引用22楼hualilihua的回复:
引用8楼x2670316290的回复:引用6楼hualilihua的回复:唉!我终于有点明白了,交流会上老大说过的话:“中国硬编码的人太多了”不明白兄弟,您的意思,请明示。发错啦不好意思lz不要有意见呀
没事,帮我看看这个东西什么情况引起的。
解决方案:
引用24楼yanbuodiao的回复:
C#codeparameters[0].Value=BeginTime;parameters[1].Value=EndTime;//这里的BeginTime和EndTime是啥类型的?先强转成DateTime类型的试试个人猜测的
传过来的时候,已是DateTime类型
解决方案:
returnDbHelperSQL.Query(strSql.ToString(),parameters);//按照你的意思应该是这句执行的时候卡住了建议lz跟进去断点直接打到真正执行的那句完后跟一下//各个变量的值把Sql语句放到查询分析器中注意也是用参数查询看看问题到底在哪了
解决方案:
引用27楼yanbuodiao的回复:
C#codereturnDbHelperSQL.Query(strSql.ToString(),parameters);//按照你的意思应该是这句执行的时候卡住了建议lz跟进去断点直接打到真正执行的那句完后跟一下//各个变量的值把Sql语句放到查询分析器中注意也是用参数查询看看问题到底在哪了
是的,跟进去了的,就是在执行这个语句的时候报超时。
解决方案:
变量的值就那么两个,一个开始时间,一个结束时间
解决方案:
strSql.Append(@"groupbyRegInfo.GameKeyorderbyRegInfo.GameKey");//这句在传参数的没有
declare@BeginTimeDateTime,……--lz自己补全直接在查询分析器中试试selectGameKeyas[GameKey],max(GameName)as[GameName],COUNT(1)as[TCount],sum(RegInfo.OkMoney)as[TMoney],sum(RegInfo.ClearingMoney)as[ClearingMoney],sum(RegInfo.ReturnMoney)as[ReturnMoney]fromRegInfowherePostTimebetween@BeginTimeand@EndTimegroupbyRegInfo.GameKeyorderbyRegInfo.GameKey
解决方案:
语句本身是没有问题的,这种肯定是性能上的小细节哪里没有对。测试了一天才发现是这个参数引起的,很是没有想到
解决方案:
引用30楼yanbuodiao的回复:
C#codestrSql.Append(@"groupbyRegInfo.GameKeyorderbyRegInfo.GameKey");//这句在传参数的没有SQLcodedeclare@BeginTimeDateTime,……--lz自己补全直接在查询分析器中试试selectGameKeyas[GameKey],max(GameN……
谢谢兄弟,积极回复,跟踪过SQL,在查询分析器里执行很快,跟字符串拼接是一样的效果。
解决方案:
引用32楼x2670316290的回复:
引用30楼yanbuodiao的回复:C#codestrSql.Append(@"groupbyRegInfo.GameKeyorderbyRegInfo.GameKey");//这句在传参数的没有SQLcodedeclare@BeginTimeDateTime,……--lz自己补全直接在查询分析器中试试selec……
我去灵异了?搞不懂了……
解决方案:
个人感觉程序不骗人lz在好好跟跟一句一句的跟还有就是有些问题在这个当口就是找不到原因晚上回去睡觉的在想想没准一下就通了个人经验或者找别人跟跟或许有想不到的效果
解决方案:
引用34楼yanbuodiao的回复:
个人感觉程序不骗人lz在好好跟跟一句一句的跟还有就是有些问题在这个当口就是找不到原因晚上回去睡觉的在想想没准一下就通了个人经验或者找别人跟跟或许有想不到的效果
也许吧。
解决方案:
引用35楼x2670316290的回复:
引用34楼yanbuodiao的回复:个人感觉程序不骗人lz在好好跟跟一句一句的跟还有就是有些问题在这个当口就是找不到原因晚上回去睡觉的在想想没准一下就通了个人经验或者找别人跟跟或许有想不到的效果也许吧。
找到原因给贴上来不相信灵异
解决方案:
我测试了下没错(数据就几条)
解决方案:
给你断代码测试下哪个耗的时间多、DateTimedt=DateTime.Now;你的代码....DateTimedt2=DateTime.Now;TimeSpants=dt2-dt;doubleMill=ts.TotalMilliseconds;MessageBox.Show(Math.Round(Mill/1000,3).ToString()+"毫秒");
解决方案:
SqlParameter确实有效率问题,但是可以防注入。所以我总是叫别人用SqlParameter,我自己拼字符串,因为我的程序是生成的。但是SqlParameter引起超时还真不知道
解决方案:
用sql参数的话优化器可能无法知道输入的数据从而造成全表扫描,所以要比前者慢
解决方案:
直接newSqlParameter("@BeginTime",BeginTime),newSqlParameter("@EndTime",EndTime)};试试,其实不需要写那么咯嗦的写法
解决方案:
SqlParameter效率高不用考虑应为:占用数据库资源采用sql每次数据库都为认为是新的语句采用SqlParameter数据库里产生的语句只有一条检测数据库,便知道第一种:数据库参生很多不同的对象在一个应用中第二种:数据库参生一个对象在一个应用中有时查询几条比几十条还慢不防考虑考虑改成后者
解决方案:
SqlParameter数据库里产生的语句只有一条只是参数不同语句在数据库里语句只有一个
解决方案:
这是血的教训
解决方案:
引用42楼tigerleq的回复:
SqlParameter效率高不用考虑应为:占用数据库资源采用sql每次数据库都为认为是新的语句采用SqlParameter数据库里产生的语句只有一条检测数据库,便知道第一种:数据库参生很多不同的对象在一个应用中第二种:数据库参生一个对象在一个应用中有时查询几条比几十条还慢不防考虑考虑改……
确实有这么回事,拼sql占用的资源多,但是这个资源有淘汰机制,不是主要问题。主要的问题是SqlParameter方式的sql语句只需要解析一次,基本相当与存储过程,记得2008才采取sql语句缓存的形式(也许2005也支持,没用过)。在这种情况下,问题转化为到底解析SqlParameter参数效率高,还是解析sql语句效率高。经个人测试,SqlParameter解析的效率是很低的,当然sql语句较长而SqlParameter较少的时候也会有反例,我认为这种情况存储过程更合适。几年前,我个人的做法在第一次执行大SQL之前生成存储过程,不过现在不关注这些东西了。
解决方案:
另外一直有一个问题,2008解析SQL比2000慢太多,不知道是什么原因,估计与这个缓存有很大关系,但是不知道怎么禁用它。因为我可以用程序判断应该用SQL语句还是存储过程,是需要缓存还是不需要,被缓存的感觉真不爽。
解决方案:
用sql参数的话优化器可能无法知道输入的数据从而造成全表扫描,所以要比前者慢
解决方案:
strSql.Append("wherePostTimebetween@BeginTimeand@EndTime");SqlParameter[]parameters={newSqlParameter("@BeginTime",SqlDbType.DateTime),newSqlParameter("@EndTime",SqlDbType.DateTime)}//这里,我没有看到任何赋值语句,SqlParameter[0],SqlParameter[1]的值是什么?还是默认值?
解决方案:
效率方面不了解,不过好像后者安全性高一些
解决方案:
该回复于2012-02-10 09:46:21被版主删除