10

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 を使用しないように再構築する必要はありません。

どんな助けでも感謝します。クエリの実行プランは次のとおりです

4

1 に答える 1