【问题标题】:Entity framework execution time实体框架执行时间
【发布时间】:2013-01-20 08:25:42
【问题描述】:

我注意到今天使用 Entity Framework 的执行时间存在巨大差异。我想知道为什么第一个语句有这么多开销。对于这个查询,我正在从数据库中检索 5500 个趋势数据值(这应该没什么大不了的)。

这是我之前使用的语句:

TrendDataValues = new ObservableCollection<TrendDataValue>(_trendDataContext.TrendDatas.First(td => td.Id == argument.TrendDataId)
                                                                            .TrendDataValues
                                                                            .Where(tdv => tdv.ValueStartTimestamp >= argument.MinValue
                                                                                       && tdv.ValueStartTimestamp <= argument.MaxValue));

但是,此语句需要 10 秒才能运行。

我已将第一个语句重写为以下语句。这将检索完全相同的数据。但是,此语句会在 0.2 秒内返回值。

 TrendDataValues = new ObservableCollection<TrendDataValue>(from td in _trendDataContext.TrendDatas.Where(d => d.Id == trendDataId)
                                                            from tdv in td.TrendDataValues
                                                            where tdv.ValueStartTimestamp >= argument.MinValue
                                                               && tdv.ValueEndTimestamp <= argument.MaxValue
                                                            select tdv);

有人可以澄清这两种说法的区别吗?

【问题讨论】:

  • 在第一个中,您将开始时间与最小值和最大值进行比较,在第二个中,您将开始时间与最小值进行比较,结束时间与最大值进行比较。这只是一个错字吗?
  • 啊,是的,这是一个错字。但是,在当前情况下,它不会有什么不同,因为在这种情况下,结束和开始时间戳是相等的
  • 您的分析工具是否建议花费时间在 SQL Server 上执行查询?如果有,这两个执行计划有什么区别(如果有的话)。

标签: c# .net linq frameworks entity


【解决方案1】:

建议:下载http://www.linqpad.net/

将 LINQ-pad 连接到您的数据库。

运行这两个查询并查看 SQL 选项卡,看看查询生成的 SQL 是否存在差异。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    如果链式方法或查询语法相同,则生成的 sql 将相同,乍一看,在第二个示例中您隐式创建连接,即两个 from / where 语句将类似于内部加入,而在第一个中,您没有并且可能正在创建某种形式的笛卡尔积,链式方法必须搜索。

    正如其他人建议的那样,去使用 LinqPad 并检查生成的 sql,我敢打赌它不一样。

    附:实际上,第二个示例实际上需要更长的时间来编译!但如果两个示例在逻辑上相同,则方法和查询语法将具有相同的执行速度。

    【讨论】:

    • 嗨,保罗,我花了一段时间才弄清楚记事本(通过第一个示例),但之后就变得清晰了。第一个示例仅查询 Trenddata-parent,然后将所有值加载到内存中,并对内存中的值进行 linq 查询,而第二个示例根据我的查询返回带有趋势数据值的标量表。
    • 是的 Linqpad 简单但功能强大。在这种情况下,通常最好自己进行故障排除:)
    • 课程用马...我经常使用 linqpad 作为 RAD 工具,它具有 RAD 带来的所有好处...如果您更擅长编写 SQL,那么它也可能值得一试 Linqer,一个简单的 SQL 到 Linq 的转换工具
    【解决方案3】:

    根据上述答案的建议,我已经在 linqpad 中测试了这两个查询。

    第一个运行以下查询:

    SELECT TOP (1) [t0].[Id], [t0].[Tag], [t0].[Description], [t0].[PollingInterval], [t0].[Compression], [t0].[PlcLogDataTypeValue]
    FROM [TrendDatas] AS [t0]
    WHERE [t0].[Id] = @p0
    

    第二个运行以下查询:

    SELECT [t1].[Id], [t1].[ValueStartTimestamp], [t1].[ValueEndTimestamp], [t1].[Value], [t1].[SerieNumber], [t1].[TrendData_Id]
    FROM [TrendDatas] AS [t0], [TrendDataValues] AS [t1]
    WHERE ([t1].[ValueStartTimestamp] >= @p0) AND ([t1].[ValueStartTimestamp] <= @p1) AND ([t0].[Id] = @p2) AND ([t1].[TrendData_Id] = [t0].[Id])
    

    显然第一条语句只返回trenddata-parent 对象。我猜它是如何迭代它的值(子元素)的,因为我没有看到引用 TrendDataValues 表的查询或连接,但我猜这不会很漂亮。

    第二个查询返回一个更好的结果,它完全符合我的要求。

    感谢您的支持和 +1 的回答!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-16
      • 1970-01-01
      • 2017-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多