以下代码的潜在性能问题是什么?您建议如何修复它?

时间:2016-08-17 09:19:22

标签: sql sql-server database

我接受了微软的采访,他们问我以下问题!我不知道如何解决它,我很有兴趣知道解决方案是什么  p.s:只有我才能提高自己,因为我被拒绝了。

无论如何:请假设EmployeeRepository和ServiceTicketsRepository正在实现EntityFramework ORM存储库。实际存储是云中的SQL数据库。 额外奖励:反模式的名称是什么?

 //
 // Return overall number of pending work tickets for all employees in the repository
 //
 public int GetTicketsForEmployees()
{
EmployeeRepository employeeRepository = new EmployeeRepository();
       ServiceTicketsRepository serviceTicketRepository = new ServiceTicketRepository();

       int ticketscount = 0;

       var employees = employeeRepository.All.Select(e => new EmployeeSummary { Employee = e }).ToList();
       foreach (var employee in employees)
       {
           var tickets = serviceTicketRepository.AllIncluding(t => t.Customer).Where(t => t.AssignedToID ==employee.Employee.ID).ToList();
           ticketscount += tickets.Count();
       }

       return ticketscount;
 { 

2 个答案:

答案 0 :(得分:0)

我不是C#,但我可以从我这边看到的是你没有使用任何加入程序。

如果您有100万名员工,并且每位员工有大约1000张门票。

您将进行10亿次查询(包括循环):/并且您只想返回员工报告的票数

编辑:我认为您正处于急切加载状态,在循环过程中,您的EntityFramework实例将在循环的所有持续时间内打开。

编辑2:使用内部联接,您不必重复t => t.AssignedToID ==employee.Employee.ID联接将为您执行此操作。

答案 1 :(得分:0)

这称为 1 + N反模式。这意味着您将对数据库进行1 + N次往返,其中N是Employee表中的记录数。

它将执行1次查询以查找所有员工,然后为每位员工执行另一次查询以查找他们的票证,以便对其进行计数。

性能问题是,当N增长时,您的应用程序将执行越来越多的往返,每次往返几毫秒。即使只有1000名员工,这也会很慢。

除了往返之外,此代码还会获取Employee表中所有行的所有列以及Ticket表中的所有列。这将累积大量字节,并且当员工和票证的数量增加到很大时,最终可能会导致内存不足。

修复方法是执行一个查询,该查询计算属于员工的所有票证,然后仅返回计数。这将成为一次往返,仅通过网络发送几个字节。