-1

我在我的 C# .NET 应用程序中针对使用 MySQL .NET 连接器 6.6.5 的 MySQL 数据库运行 Entity Framework 5。

通常,当 EF 不够快时,我会求助于存储过程或直接执行 SQLcontext.Database.SqlQuery 但是,我最近遇到了一个问题,即 SQL 调用实际上比它的 EF 等价物花费的时间要长得多,我想知道是否有人知道这是为什么?

这是(慢速)SQL 查询:

public sbyte? getFirstRouteTypeFromStop(string primaryCode) {

    string sql = string.Format("SELECT r.route_type FROM stoptimes st INNER JOIN trips t ON st.trip_id = t.trip_id INNER JOIN routes r ON t.route_id = r.route_id WHERE st.stop_id = '{0}' LIMIT 1;", primaryCode);
    return context.Database.SqlQuery<sbyte?>(sql).FirstOrDefault();

}

这是(快速)EF代码:

public sbyte? getFirstRouteTypeFromStop(string primaryCode) {

    return context.stoptimes.Where(st => st.stop_id.Equals(primaryCode)).FirstOrDefault().trip.route.route_type;

}

这个方法在循环中被重复调用,EF 快了很多。(至少 1000%)为什么?

重要笔记:

  • MySQL 数据库对所有这些列进行了适当的索引。
  • 当原生 SQL 查询直接在 MySQL 中运行时,它的执行速度似乎比在 C# 应用程序中运行时快得多——我怀疑这是一个非常重要的观察结果。
4

3 回答 3

2

您在 SqlQuery 中使用了 INNER JOIN,这意味着:

选择的总行数 =(停止时间的行数)*(路线中的行数)*(行程中的行数)

然后在那个巨大的列表上执行“WHERE st.stop_id ='{0}'”......我怀疑这是sql查询中的问题......内部连接进行了大量选择并从中过滤记录。 ..

而 EF 代码仅在表停止时间上过滤

Where(st => st.stop_id.Equals(primaryCode))

所以它使过滤快速,然后在单个选择的记录上,获取路线和行程。

注意:- 尝试使用 LEFT OUTER JOIN... 这将使您的查询更快。

希望能帮助到你...

于 2013-10-18T12:15:57.023 回答
0

也许您已经在内存中拥有全部或部分Stoptimes(及其导航属性,如trip和)。route如果是这种情况,EF 只会点击一次数据库(或者至少不是在循环的每次迭代中)。随着SQLQuery您在循环的每次迭代中进入数据库。也许primaryCode在循环中重复了很多?或者,也许您在应用程序中检索Stoptimes以前的代码而不释放上下文?

于 2013-10-18T11:22:33.847 回答
0

尝试更改 TSQL

SELECT r.route_type 
  FROM stoptimes st 
  JOIN trips t 
    ON st.trip_id = t.trip_id 
   AND st.stop_id = '{0}'
  JOIN routes r 
    ON t.route_id = r.route_id 
 LIMIT 1;
于 2013-10-18T12:41:06.750 回答