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

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

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

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

public class OrderItem
    public string Id{ get; set; }
    public string OrderId{ get; set; }//订单编号
    public string ProductId{ get; set; }//商品ID
    public 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 OrderItems
    WHERE 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

  距离上一篇博文更新已经两个月过去了。在此,先表一表这两个月干了些啥:  世界那么大,我也想去看看。四月份的时候,我入职了上海的一家电商公司,职位是.NET高级开发工程师。工作一个月,最大的感受是比以前小城市匆忙了许多,工作压力大了许多,开发方式更加的正规,不过各种流程也更加的繁杂细琐。在写代码的时候,一定要严谨细心,该验证参数合法性的时候验参,该抛异常的时候抛异常,该写日志的时候写日志,因...
linq to sql 是一个代码生成器和ORM工具,他自动为我们做了很多事情,这很容易让我们对他的性能产生怀疑。但是也有几个测试证明显示在做好优化的情况下,linq to sql的性能可以提升到ado.net datareader性能的93%。 因此我总结了linq to sql的10个性能提升点,来优化其查询和修改的性能。 1. 不需要时要关闭 DataContext的ObjectTrac...
linq查询结果进行迭代时,linq才去执行查询,就是说{在迭代时,才真正执行}.这是延迟操作的一种性能提升的表现. 但试想下,需要对结果进行第2次,第3次...,那么这种延迟执行,却是性能的一个瓶颈. 测试如下代码: public IEnumerable GetValue() List lst = new Lis
LINQ to SQL is a technology that enables developers to use LINQ (Language Integrated Query) to access data stored in Microsoft SQL Server databases. With LINQ to SQL, developers can write queries using C# or VB.NET instead of SQL, which provides a more intuitive and type-safe way to work with data. LINQ to SQL provides a mapping between the database schema and the classes in the application, allowing developers to work with data as objects rather than as rows in a table. This makes it easier to write and maintain code, as well as improving performance by reducing the number of database calls needed to retrieve or update data. LINQ to SQL also supports features like change tracking, which allows developers to detect and handle changes to data made by other users or applications. It also provides support for transactions, allowing developers to ensure that multiple database operations are atomic and consistent. Overall, LINQ to SQL is a powerful tool for developers working with Microsoft SQL Server databases, offering a more productive and efficient way to access and manipulate data.
springboot整合mybatis报错:Invalid default: public abstract java.lang.Class org.mybatis.spring.annotation... random模块 time模块 springboot整合mybatis报错:Invalid default: public abstract java.lang.Class org.mybatis.spring.annotation... random模块 time模块