2

そのため、EF がアプリ用に生成するクエリを掘り下げていたところ、奇妙な sqlAny呼び出しの生成に気付きました。それらは過度に複雑なようです。Any生成するように見える-elsecase when (x) then 1 when (not x) then 0 endだけを使用しないのはなぜですか? Anyこのように、SQL サーバーは、返すべき場合に同じクエリを 2 回実行する必要がありfalseます。を使用してこれらのケースでより高速と思われる回避策を思いつきましたがWhere(cond).Select(q => true).FirstOrDefault()、これが単なる見落としなのか、それとも私が見逃している意味があるのか​​ にまだ興味があります。

context.Books.Any(b => b.Id == bookId);

declare @p__linq__0 Int = 1;

SELECT 
CASE WHEN ( EXISTS (SELECT 
    1 AS [C1]
    FROM [Books] AS [Extent1]
    WHERE [Extent1].[ID] = @p__linq__0
)) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT 
    1 AS [C1]
    FROM [Books] AS [Extent2]
    WHERE [Extent2].[ID] = @p__linq__0
)) THEN cast(0 as bit) END AS [C1]
FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]

context.Books.Where(b => b.ID == bookId).Select(b => true).FirstOrDefault();

declare @p__linq__0 Int = 1;

SELECT TOP (1) 
cast(1 as bit) AS [C1]
FROM [Books] AS [Extent1]
WHERE [Extent1].[ID] = @p__linq__0
4

1 に答える 1

1

何かが存在しないことを確認した後、それが実際に存在しないことは明らかなので、実際に存在しないかどうかを agin で確認する必要はありません。これは、linq が過度に複雑なクエリを生成しているケースの 1 つにすぎません。あなたの回避策は機能しますが、必ずしも理解しやすいとは限りません。そのため、実際にパフォーマンスの問題が発生するまで、元の linq のパフォーマンス ヒットを取ることをお勧めします。Id 列にインデックスがあることを確認してください。

于 2013-01-28T14:48:58.173 に答える