距离上一篇博文更新已经两个月过去了。在此,先表一表这两个月干了些啥:

  世界那么大,我也想去看看。四月份的时候,我入职了上海的一家电商公司,职位是.NET高级开发工程师。工作一个月,最大的感受是比以前小城市匆忙了许多,工作压力大了许多,开发方式更加的正规,不过各种流程也更加的繁杂细琐。在写代码的时候,一定要严谨细心,该验证参数合法性的时候验参,该抛异常的时候抛异常,该写日志的时候写日志,因为一个不小心而报黄页或者主流程无法顺利进行下去,是很没面子的事情。另外,我也更加关注代码的性能问题,开发环境和生产环境的数据量根本不是一个数量级的,也许在开发环境页面加载速度很快一旦上了产线却慢得无法忍受。

  好了,废话少说,言归正传。昨天,Leader安排了一个性能优化的任务。商家要导出订单信息,如果查询的订单时间间隔比较小,没什么问题,查询的订单时间跨度大了,就非常非常非常慢了。项目使用的ORM是LINQ to SQL,至于为什么要使用,这属于历史遗留问题了。

  有一个订单明细表,里面有数十个字段,为了简化问题,我们建一个简单的实体:

public class OrderItem
{public string Id{ get; set; }public string OrderId{ get; set; }//订单编号public string ProductId{ get; set; }//商品IDpublic int ProductQuantity{ get; set; }//商品数量
}

  一个方法一个方法排查,最后找到了问题的所在:

List<OrderItem> orderItems=OrderRepository.Find(orderItem=>orderIdList.Contains(orderItem.OrderId)).ToList();

  orderIdList是一个List<string>集合,存储了查询时间段内的订单编号。当订单编号的数量大于50时查询就开始变慢,大于100时就非常慢了。我在orderIdList里填充了1000个有效的订单编号,然后用SqlServer Profiler监控,发现上面一句LINQ查询表达式动态编译成SQL语句竟然花费了几十秒的时间,生成的SQL大概如下:

    SELECT Id,OrderId,ProductId,ProductQuantity   FROM OrderItemsWHERE OrderId IN (......)

  上面的SQL执行时间大约是0.7秒,已经为订单编号OrderId字段建立了索引,测试数据库里的数据大约是55万条。

    为了解决上面LINQ查询表达式动态编译成SQL耗时比较长的问题,最后决定直接执行SQL语句,并且IN查询改为JOIN查询,简单粗暴。解决方法如下:

//创建临时表SQL,存储查询时间段内的订单编号
string createSql = "CREATE TABLE #TmpOrderId(OrderId varchar(36));";//订单编号插入SQL
string orderIds = orderIdList.Aggregate(string.Empty,(current,id) => current + ("('" + id + "'),"));
orderIds = orderIds.Remove(orderIds.LastIndexOf(','));
string insertSql = "INSERT INTO #TmpOrderId VALUES " + orderIds + ";";//JOIN查询SQL
string joinSql = "SELECT T1.Id,T1.OrderId,T1.ProductId,T1.ProductQuantity FROM OrderItems AS T1 JOIN #TmpOrderId AS T2 ON T1.OrderId=T2.OrderId;";//三条SQL语句要放在一个会话里执行,否则会报找不到临时表#TmpOrderId异常
IEnumerable<OrderItem> query = DataContext.ExecuteQuery<OrderItem>(createSql + insertSql + joinSql);

  最后,采用该解决方法,订单明细数据基本瞬间就查询出来了,效果拔群啊,该优化任务圆满完成。

转载于:https://www.cnblogs.com/daretodream2014/p/4523994.html

也记一次性能优化:LINQ to SQL中Contains方法的优化相关推荐

  1. 浅谈Linq to SQL中的模式

    学习Linq to SQL也有一段时间了,感叹它做为ORM虽然简单但是功能效率都还不错,从编译器和语言层面支持上来看,它是其他ORM工具不能比的.Linq to SQL中运用了很多模式对自身的效率进行 ...

  2. linq to sql中的自动缓存(对象跟踪)

    这篇东西应该至少一年前就写的,不过因为个人太懒,一直没记下来,今天补上. linq to sql中,对于同一个DataContext上下文环境,根据表主键选择记录时(当然这里所指的"记录&q ...

  3. 【转】 LINQ TO SQL中的selectMany

    首先看SelectMany的定义: Queryable中的SelectMany 方法:将序列的每个元素投影到一个 IEnumerable<(Of <(T>)>) 并将结果序列组 ...

  4. LINQ TO SQL中还是用传统的连接串方式建立DbContext更好些

        首先,在LINQTOSQL中可以这样建立一个dbcontext      private TEntity GetOriginal(TEntity entity)         {       ...

  5. 在Linq to Sql中管理并发更新时的冲突(3):使用记录的时间戳进行检测

    我们描述了Linq to Sql检测在更新时是否产生了冲突的基本方法:将该记录每个字段原来的值和更新时的值进行对比,如果稍有不同则意味着记录被修改过,因此产生了更新冲突.不过您是否有这样的感觉,这种方 ...

  6. 在LINQ to SQL中使用Translate方法以及修改查询用SQL

    目前LINQ to SQL的资料不多--老赵的意思是,目前能找到的资料都难以摆脱"官方用法"的"阴影".LINQ to SQL最权威的资料自然是MSDN,但是M ...

  7. Linq To Sql中实现Left Join与Inner Join使用Linq语法与lambda表达式

    当前有两个表,sgroup与sgroupuser,两者通过gKey关联,而sgroup表记录的是组,而sgroupuser记录是组中的用户,因此在sgroupuser中不一定有数据.需要使用Left ...

  8. linq to sql 中,如何解决多条件查询问题,答案,用表达式树! (下)

    ,我们做了基于linq to sql 的多条件组合查询,但通过监视数据库发现,这样做的成本比较高,每次都要取出全部的数据到内存进行筛选.如何从真正意义上做到延迟加载,即一次只从数据库中取我们需要的用到 ...

  9. linq to sql中修改连接字符串

    如果在类库中在添加linq to sql并连接完数据库服务器后会自动生成settings.settings文件,app.config文件用于存储连接字符串(图一) 如要修改连接字符串要修改哪个还是要全 ...

最新文章

  1. 10月25日lol服务器维护,《LOL》lol10月25日停机维护到什么时候 10.25维护结束时间...
  2. 【Python】Python错误、异常和模块(长文系列第4篇)
  3. 2.vue 安装教程
  4. MySQL大表优化技术要点科普
  5. 手机吞吃蛇游戏的设计与开发
  6. SQL Management Studio Express 安装缺少MSXML6解决
  7. [转]cscope在windows下使用mingw编译的方法
  8. 【SimpleITK】分割label覆盖到原图上显示
  9. MVC 中 Html.RenderPartial()与Html.Partial()区别
  10. 同步发电机励磁调节实验原理_发电机组自动控制系统工作原理
  11. H桥原理、驱动及应用
  12. 谷歌学术搜索 2019
  13. 计算机教学拼音打字教案,sogo拼音输入法教案.doc
  14. OSPF详解 一看就会奥!
  15. 《计算机工程》从投稿到录用之一手经验
  16. 蚁群算法 c语言,蚁群算法(C语言实现)
  17. 阿里云虚拟机转让(RAM创建账户)
  18. 全球及中国机器视觉光源行业市场调查及投资可行性研究报告2022-2028年
  19. 全民都是评选专家,提前一天泄露 2020 博客之星最终结果
  20. 爬取京东笔记本电脑销量榜每件商品详情页url,并存入云服务器中的mysql库

热门文章

  1. pixhawk PX4FMU和PX4IO最底层启动过程分析
  2. NEUQ 2015: Bitmap(二维hash)
  3. linux删除某个path_linux 从path中去掉某个
  4. C++ 中的this指针详解及实例
  5. ROS学习笔记-ROS语音识别与语音输出[2]
  6. nodejs mysql备份_node.js实现备份mysql数据库功能
  7. 如何利用反射实现EL表达式
  8. rmi of spring
  9. JMS中queue和topic区别
  10. 【题解】luogu p1111 修复公路