EF
とLinq to entities
でいくつかのテストを行い、アプリケーションのパフォーマンスを向上させています。Linq to SQLによるエンティティ注文
私は説明できない奇妙なこと(私には)が気付くだけでなく、相当なオーバーヘッドが発生するかどうかも実際には分かりません。ここで
は私のLINQです:
var result = from n in query
orderby n.PersonId
select new
{
id = n.Id,
appointmentId = n.AppointmentId,
message = n.Message,
wasRead = n.Read,
canDismiss = (n.Appointment.Status != AppointmentStatus.Waiting),
date = n.IssueDateUtc
};
は、これは生成されたSQLです:
SELECT
[Project1].[Id] AS [Id],
[Project1].[AppointmentId] AS [AppointmentId],
[Project1].[Message] AS [Message],
[Project1].[Read] AS [Read],
[Project1].[C1] AS [C1],
[Project1].[IssueDateUtc] AS [IssueDateUtc]
FROM (SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Read] AS [Read],
[Extent1].[Message] AS [Message],
[Extent1].[IssueDateUtc] AS [IssueDateUtc],
[Extent1].[AppointmentId] AS [AppointmentId],
[Extent1].[PersonId] AS [PersonId],
CASE WHEN (NOT ((1 = [Extent2].[Status]) AND ([Extent2].[Status] IS NOT NULL))) THEN cast(1 as bit) WHEN (1 = [Extent2].[Status]) THEN cast(0 as bit) END AS [C1]
FROM [dbo].[Notification] AS [Extent1]
LEFT OUTER JOIN [dbo].[Appointment] AS [Extent2] ON [Extent1].[AppointmentId] = [Extent2].[Id]
WHERE [Extent1].[PersonId] = @p__linq__0
) AS [Project1]
**ORDER BY [Project1].[PersonId] ASC**
これはそうしながら、私は別の投影(Project1
)における基の種類結果をする必要性を理解していません
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Read] AS [Read],
[Extent1].[Message] AS [Message],
[Extent1].[IssueDateUtc] AS [IssueDateUtc],
[Extent1].[AppointmentId] AS [AppointmentId],
[Extent1].[PersonId] AS [PersonId],
CASE WHEN (NOT ((1 = [Extent2].[Status]) AND ([Extent2].[Status] IS NOT NULL))) THEN cast(1 as bit) WHEN (1 = [Extent2].[Status]) THEN cast(0 as bit) END AS [C1]
FROM [dbo].[Notification] AS [Extent1]
LEFT OUTER JOIN [dbo].[Appointment] AS [Extent2] ON [Extent1].[AppointmentId] = [Extent2].[Id]
WHERE [Extent1].[PersonId] = @p__linq__0
**ORDER BY [Extent1].[PersonId] ASC**
私はかなりの量を見つけました。 efとlinqの両方によって疑わしいSQLが生成され、私は生のsqlsを書いていないほうがいいかどうか疑問に思っています。
質問です:生成されたSQLの余分なビットを心配する何かですか?なぜその投影が必要なのですか?
編集コメントで述べたように、新たなLINQ
に追加するには、多分、詳細は実行されて以降のクエリによって引き起こされました。私は1つのクエリオブジェクトを使用するためにLINQを書き直し、結果は同じです:
dbSet.Where(n => n.PersonId == id).Select(n => new
{
Id = n.Id,
AppointmentId = n.AppointmentId,
Message = n.Message,
Read = n.Read,
CanBeDismissed = (n.Appointment.Status != AppointmentStatus.Waiting),
IssueDate = n.IssueDateUtc
}).OrderBy(n => n.Id).ToList();
実行計画(同じ両方sqls
用)
編集2
このクエリは単純なカウントから取得しました。期待
dbSet.Count(x => x.Id == 1 && x.Read == false);
SELECT
[GroupBy1].[A1] AS [C1]
FROM (SELECT
COUNT(1) AS [A1]
FROM [dbo].[Notification] AS [Extent1]
WHERE ([Extent1].[PersonId] = 19) AND (0 = [Extent1].[Read])
) AS [GroupBy1]
:
SELECT
COUNT(1) AS [A1]
FROM [dbo].[Notification] AS [Extent1]
WHERE ([Extent1].[PersonId] = 19) AND (0 = [Extent1].[Read])
私はすべて、このラッパーはから来て、なぜされている場所を得ることはありません。
私は 'query'は別のLINQツーSQLクエリであり、それはあなたが入れ子になった見たものであると仮定投影の内側にある。それはLINQでやっていることとまったく同じです。それを取り除きたいのであれば、 'OrderBy'と' Select'を 'query'に追加してください。しかし、後続のLINQクエリを使用してコードをきれいにしても、心配する必要はありません。投影には最小限のオーバーヘッドがあります。疑わしい場合は実行計画を比較してください。しかし、パフォーマンス上の問題がある場合は、その予測が原因ではありません。 –
LINQ-to-SQLが生成するクエリに関する懸念... Linq-to-SQLは優れた(ただししばしば冗長な)SQLクエリを、複雑なシナリオではさらに多く生成しています。私はそれがほとんどのプログラマーが達成するよりも優れていると言いたい。もちろん、よく書かれたLINQクエリが必要です。だから、生成されたSQLをダブルチェックするのは良いことです...しかし、一般的には、LINQは一般的にジョインやクロスアプリケーションなどを使うときに非常に良い選択肢になります。 LINQの生成されたSQL;) –
私は常に新しい何かを学んでいます。私はsgdbについて多くのことを学んだので、心配しています。私の製品は成長しています。今はdbアクセスの分析に時間を割いています。私はかなりひどいコードを見て、表現を書き直すだけで約60% 。とにかく、私は1つのクエリだけを使用してlinqを書き換えて、結果は同じでした。私は質問にそれを追加して、それをチェックしてください。私は余分なコードが使用されている匿名型のために生成されると思います。 – victor