快速业务通道

Cont()与Where().Count()有时性能差别如此之大

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-05-20

今天在修改后台用户公司管理列表时,发现列表加载超慢的bug!好几十秒啊!数据是相对其他的列表 是稍微多点,不过也就4000多条,之前是好的,为啥这么慢呢?想起我之前在此列表中加入了一个字段, 用于方便提示管理员公司的产品列表是否有修改之类的状态字段,于是可以断定是加了此字段的原因。

首先,先看看我之前是如何写这个提示状态字段的,实体中加入ContentStatus,然后直接在Linq语句 中Select 实体对象中加入ContentStatus=Product_Maintain.Count(C => C.CompanyID == company.ID && C.IsDeleted == 0 && (C.AuditStatus == 0 || C.AuditStatus == 4))>0?"产品有更新":""。这时我想应该是加入三元运算,linq在转Sql时,产生过多的,Case,when ,then语句,三元运算增加了判断会影响查询性能,于是我去掉后,再运行查看页面,仍然很慢,感觉不 出快了多少。

这时,我想起了LinqPad,看看到底转换生成了怎样的Sql语句。运用Count(条件)生成Sql代码如下 :

SELECT COUNT(*) AS [value]
     FROM (
         SELECT
             (CASE
                 WHEN ([t1].[CompanyID] = ([t0].[ID])) AND ([t1]. [IsDeleted] = @p0) AND (([t1].[AuditStatus] = @p1) OR ([t1].[AuditStatus] = @p2))  THEN 1
                 WHEN NOT (([t1].[CompanyID] = ([t0].[ID])) AND  ([t1].[IsDeleted] = @p0) AND (([t1].[AuditStatus] = @p1) OR ([t1].[AuditStatus] =  @p2))) THEN 0
                 ELSE NULL
              END) AS [value]
         FROM [Company_Product_Maintain] AS [t1]
         ) AS [t2]
     WHERE [t2].[value] = 1

这时我发现一个很简单的Count的Sql 语句,linq转换后变得如此复杂,我直接在sql server中运行此 代码,发现查询还是很慢,于是我直接把ContentStatus=Product_Maintain.Where(C => C.CompanyID == company.ID && C.IsDeleted == 0 && (C.AuditStatus == 0 || C.AuditStatus == 4)).Count()生成Sql语句为:

SELECT COUNT(*) AS [value]
     FROM [GasSNS_Company_Equipment_Maintain] AS [t1]
     WHERE ([t1].[CompanyID] = ([t0].[ID])) AND ([t1].[IsDeleted] = @p0) AND  (([t1].[AuditStatus] = @p1) OR ([t1].[AuditStatus] = @p2))

发现运行速度那是快了一个数量级啊!

后台列表查询结果速度大大提升有图为证(声明:以下图都为项目中截图,不是简单的单表查询,还连 了用户表,详细表等数量也都挺大的):

图1为Count结果,用了35秒,哇塞!

图2为Where(条件).Count()结果,同样的数据只用了4秒钟,差了10倍!

然后为了取值方面我还是加入三元运算,ContentStatus=Product_Maintain.Where(C => C.CompanyID == company.ID && C.IsDeleted == 0 && (C.AuditStatus == 0 || C.AuditStatus == 4)).Count()>0?"产品有更新":""。结果如下:

真的是Count()与 Where()区别,不可能这么大差距吧?于是我单写

Product_Maintain.Where(C => C.IsDeleted == 0 && (C.AuditStatus == 0 || C.AuditStatus == 4)).Count()与

Product_Maintain.Count(C => C.IsDeleted == 0 && (C.AuditStatus == 0 || C.AuditStatus == 4))

发现速度差不多,生成的代码是一样的。

SELECT COUNT(*) AS [value]
FROM [GasSNS_Company_Equipment_Maintain] 

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号