gpt4 book ai didi

c# - 针对特定 EF Core 查询优化未知

转载 作者:行者123 更新时间:2023-12-05 06:59:33 24 4
gpt4 key购买 nike

我有一个在 .NET Framework 和 EF Core 3.1 上运行的 webjob 项目。Web 作业处理来自 Azure 服务总线的消息并将它们保存到 Azure SQL 数据库中。

我遇到的问题是 Azure SQL 数据库为 EF Core 生成的查询生成了非常糟糕的查询计划。使用生成的查询计划,执行时间为 1-2 分钟。但是,当我使用 OPTION (OPTIMIZE FOR UNKNOWN) 时,执行时间下降到 0.01 - 0.02 分钟。

所以现在我想在 EF Core 中实现 OPTION (OPTIMIZE FOR UNKNOWN)。我发现他们在 EF Core 3.1 中添加了一个 DbCommandInterceptor,您可以在其中将内容附加到查询中:MSDOCS

public class HintCommandInterceptor : DbCommandInterceptor
{
public override InterceptionResult<DbDataReader> ReaderExecuting(
DbCommand command,
CommandEventData eventData,
InterceptionResult<DbDataReader> result)
{
// Manipulate the command text, etc. here...
command.CommandText += " OPTION (OPTIMIZE FOR UNKNOWN)";
return result;
}
}

但似乎这个拦截器会在每个查询上运行,我只希望它用于特定的查询。我可以为这个拦截器实现一个单独的 DbContext,但这似乎不是一个可靠的解决方案。有谁知道我如何以正确的方式实现它?

最佳答案

我创建了一个界面:

public interface IInterceptable
{
bool EnableCommandInterceptors { get; set; }
}

并在我的上下文类中实现它:

public bool EnableCommandInterceptors { get; set; }

在拦截器中我有:

public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result)
{
if(command.CommandText.StartsWith("SELECT")
&& eventData.Context is IInterceptable intercepatable
&& intercepatable.EnableCommandInterceptors)
{
command.CommandText += " OPTION (OPTIMIZE FOR UNKNOWN)";
}
return result;
}

这允许打开和关闭此功能,如果此特定查询是上下文实例将运行的唯一查询,这可能就足够了。如果没有,您可以向 if(command.CommandText.StartsWith("SELECT") 部分添加更多条件。

另一种方法是用 .TagWith 标记特定查询并在拦截器中查找标记文本:

if (command.CommandText.StartsWith("SELECT") 
&& command.CommandText.Contains("my tagged text"))
{
command.CommandText += " OPTION (OPTIMIZE FOR UNKNOWN)";
}

关于c# - 针对特定 EF Core 查询优化未知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64386941/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com