【发布时间】:2013-10-18 11:05:13
【问题描述】:
我在我的 C# .NET 应用程序中运行 Entity Framework 5,针对使用 MySQL .NET 连接器 6.6.5 的 MySQL 数据库。
通常,当 EF 不够快时,我会使用存储过程或使用 context.Database.SqlQuery 直接执行 SQL 但是,我最近遇到了一个问题,即 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# 应用程序中运行时快得多 - 我怀疑这是一个非常重要的观察结果。
【问题讨论】:
-
你看过EF生成的sql吗?可以发一下吗?
-
你应该跟踪数据库语句,看看 EF 对你的代码做了什么。
-
这不是一个快速的跟踪,因为那里有一个
.FirstOrDefault(),我猜它必须破坏IQueryable,并且可能意味着它被分成2个语句? (这是猜测)如果我有时间并且没有人可以给我一个快速的答案,我会关闭我的 MySQL 服务器以打开查询日志并发布结果。 -
最可能的原因是String.format函数。因为这个函数支持格式化输出,所以它需要更多的时间来分析完整的输入并在需要的地方替换
-
只需在 IQueryable 上调用 .ToString() 即可查看生成的 SQL 语句。你不需要对你的服务器做任何事情
标签: c# mysql .net sql entity-framework