1

我注意到今天使用 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);

有人可以澄清这两个陈述之间的区别吗?

4

3 回答 3

1

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

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

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

希望这可以帮助!

于 2013-02-05T12:05:21.633 回答
1

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

正如另一个dood建议去使用LinqPad并检查生成的sql,我敢打赌它不一样。

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

于 2013-02-05T12:11:27.187 回答
0

正如上面答案中的建议,我已经在 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的答案!

于 2013-02-05T12:34:30.020 回答