100億行のテーブルがあります。where clausule でクエリを実行し、値がハードコードされている場合 ( tabulka = tabulka.Where(x => x.Value.Contains("value")
SQL クエリはバッチとして SQL に送信されます。約 5 秒かかりました。値がハードコードされていない場合 ( tabulka = tabulka.Where(x => x.Value.Contains(value)
)、クエリは RPC を送信し、15 秒かかりました。
これは、EF が ( Profiler から) SQL に送信する実際の例です。
exec sp_executesql N'SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Tabulka] AS [Extent1]
WHERE ([Extent1].[Column] LIKE @p__linq__0 ESCAPE N''~'') AND ([Extent1].[Column] LIKE @p__linq__1 ESCAPE N''~'')
) AS [GroupBy1]',N'@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)',@p__linq__0=N'%text1%',@p__linq__1=N'%text2%'
これには 15 秒かかります。
OPTION (RECOMPILE) を追加すると、5 秒かかりました。
exec sp_executesql N'SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Tabulka] AS [Extent1]
WHERE ([Extent1].[Column] LIKE @p__linq__0 ESCAPE N''~'') AND ([Extent1].[Column] LIKE @p__linq__1 ESCAPE N''~'')
) AS [GroupBy1] OPTION (RECOMPILE)',N'@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)',@p__linq__0=N'%text1%',@p__linq__1=N'%text2%'
単純なクエリに書き直すと、5 秒もかかります。
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Tabulka] AS [Extent1]
WHERE ([Extent1].[Column] LIKE '%text1%' AND [Extent1].[Column] LIKE '%text2%')
) AS [GroupBy1]
問題は、EFにバッチとして送信させるか、15秒ではなく5秒かかるようにする方法です。
これらのクエリは単なるデモです。実際のクエリはもっと複雑になる可能性があり、IQueryable を使用しないように再構築する必要はありません。
どんな助けでも感謝します。クエリの実行プランは次のとおりです