2013-02-05 51 views
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)); 

不過,這一說法接管秒運行。

我已將第一條語句改寫爲以下語句。這將檢索完全相同的數據。但是,此語句返回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); 

有人可以澄清兩個陳述之間的區別嗎?

+0

在第一個比較開始時間的最小值和最大值,在第二個比較開始時間的最小值和結束時間的最大值。這只是一個錯字嗎? – juharr

+0

啊,是的,這是一個錯字。但是,在目前的情況下,它不會產生任何影響,因爲在這種情況下,結束和開始時間戳相等 –

+0

您的分析工具是否建議在SQL Server上執行查詢所用的時間?如果是這樣,兩個執行計劃(如果有的話)有什麼區別。 –

回答

1

建議:下載http://www.linqpad.net/

連接LINQ墊到您的數據庫。

運行這兩個查詢並查看SQL選項卡以查看查詢生成的SQL是否存在差異。

希望這會有所幫助!

1

鏈式方法或查詢語法(如果它們相同)生成的sql將是相同的,乍一看,在第二個示例中,您隱式地創建了一個連接,即兩個from/where語句的作用類似於內部連接,而在第一次你不這樣做,並且可能創建鏈式方法必須搜索的某種形式的笛卡爾產品。

由於其他dood建議去使用LinqPad和檢查出生成的SQL,我敢打賭它是不一樣的。

P.S.實際上,第二個例子實際上需要更長的時間來編譯!但如果兩個示例在邏輯上相同,則方法和查詢語法將具有相同的執行速度。

+0

嗨保羅,我花了一段時間才弄清楚記事本(通過第一個例子),但之後變得清晰。第一個示例只查詢trenddata-parent,然後將所有值加載到內存中,並對其內存中的值執行linq查詢,而第二個示例則根據我的查詢返回標量表和trenddata值。 –

+0

是Linqpad簡單但功能強大。在這種情況下進行故障排查通常會更好:) – mortb

+0

課程中的馬......我使用linqpad作爲一種RAD工具,它具有RAD帶來的所有優點......如果您在家中編寫SQL更多,那麼Linqer也是值得的,Linqer是一個簡單的SQL到Linq轉換工具 –

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父對象。我猜測它是如何遍歷它的值(子元素),因爲我沒有看到引用TrendDataValues表的查詢或連接,但我猜這不會很漂亮。

第二個查詢返回的結果與我所要求的完全匹配。

感謝您的支持和+1的答案!