1

今日、EntityFrameworkの実行時間に大きな違いがあることに気づきました。最初のステートメントになぜこれほど多くのオーバーヘッドがあるのか​​知りたいです。このクエリでは、データベースから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);

誰かが2つのステートメントの違いを明確にすることができますか?

4

3 に答える 3

1

提案: ダウンロードhttp://www.linqpad.net/

LINQ-pad をデータベースに接続します。

2 つのクエリを実行し、[SQL] タブを見て、クエリによって生成される SQL に違いがあるかどうかを確認します。

お役に立てれば!

于 2013-02-05T12:05:21.633 に答える
1

チェーンされたメソッドまたはクエリ構文が同じ場合、結果の sql は同じになります。一見すると、2 番目の例では暗黙的に結合を作成しているように見えます。つまり、2 つの from / where ステートメントは内部結合と同様に機能しますが、最初は、チェーンされたメソッドが検索しなければならない何らかの形式のデカルト積を作成していません。

他のドゥードがLinqPadを使用して生成されたSQLをチェックアウトすることを示唆しているように、私はそれが同じではないに違いない.

PS事実上、2番目の例は実際にはコンパイルに時間がかかります! ただし、両方の例が論理的に同一である場合、メソッドとクエリの構文は同じ実行速度になります。

于 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

2 つ目は、次のクエリを実行します。

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 テーブルを参照するクエリまたは結合が表示されないため、その値 (子要素) をどのように反復しているかを推測していますが、これはうまくいかないと思います。

2 番目のクエリは、私が求めているものと正確に一致するより良い結果を返します。

あなたのサポートに感謝し、答えを+1してください!

于 2013-02-05T12:34:30.020 に答える