当前位置: 首页 > 面试题库 >

为什么实体框架会生成缓慢的过度设计的SQL?

沈永新
2023-03-14
问题内容

我有以下代码:

DbSet<TableName> table = ...// stored reference

var items = from n in table where
            n.Name.ToUpper().Contains(searchString.ToUpper().Trim())
            select n;
WriteToLog( items.ToString() );

最后一行输出生成的SQL。这是我得到的:

SELECT 
    [Extent1].[Name] AS [Name],
    // all the other columns follow
FROM (SELECT 
  [TableName].[Name] AS [Name],
  // all the other columns follow
FROM [dbo].[TableName] AS [TableName]) AS [Extent1]
WHERE ( CAST(CHARINDEX(LTRIM(RTRIM(UPPER(@p__linq__0))), UPPER([Extent1].[Name])) AS int)) > 0

您会看到,虽然有SELECT-from-,SELECT但它完全是多余的-
一个SELECT就足够了。尽管表很小,但使用EF的代码在该查询上运行的时间超过半分钟,并且超时。

为什么会生成此过度设计的SQL查询?如何使EF生成更好的查询?


问题答案:

它通过转换表达式树来生成结果SQL。似乎过度设计(例如,使用子查询)是完成转换方式的副作用。转换的细节是专有且复杂的,并且结果不应该是人类可读的。

问题尚不完全清楚-您正在尝试解决一个我认为可能不是问题的问题。尝试将生成的查询与您自己的查询进行比较-我猜想查询优化器将使这种简单的优化工作变得简短。

我的猜测(除非出现LINQ to Entities
MS开发人员,否则这可能是您可以得到的最好的答案)是他们确实在这样做:生成最有效的查询,但是却要将查询优化到他们已经花了数百或数千个工作日的时间:SQL
Server中的查询优化器。



 类似资料:
  • 问题内容: 为什么实体框架的DbContext.Find()会生成带有选择顶部2和派生表的查询?根据定义,查询是通过主键查找的,该键应该是唯一的。 问题答案: 首先检查具有给定键的实体是否已在上下文中。如果不是,它将查询数据库。在这种情况下,它可能使用的LINQ查询。如果结果具有多个实体,则转换为能够引发异常。 因此,为什么不使用(将转换为)。我不知道,但我想我想检查一下该实体在数据库中是否确实是

  • 问题内容: 我尝试通过使用实体框架连接MySql数据库,但Visual Studio不想生成* .edmx? 我在db中有1个表, -选择ado.net edm,- 选择从数据库生成 -选择 db-在这里我认为我应该选择表,但是 向导关闭 我尝试使用其他版本的EF,但是仍然无法正常工作。问题是什么? 我的软件: -Windows 7 * 64 -vs 2017社区 -mySql 8.0社区 问题答

  • 问题内容: 是因为我们应该加载类(例如),创建实例,然后搜索适当的方法,打包参数,然后仅调用方法?因此,大多数时间都花在了这些操作上,而不是花在对象上的显式方法调用上,对吧? 问题答案: 使用反射时,每次执行时都需要验证您执行的每个步骤。例如,当您调用一个方法时,它需要检查目标是否实际上是该方法的声明者的实例,是否具有正确数量的参数,每个参数是否具有正确的类型,等等。 绝对没有内联或其他性能技巧的

  • 我们看到,前几个流需要大约100ms来注册,当它达到300时,注册每个流需要7秒。这些流本质上是相同的(它们只是记录一条信息消息并返回)。 如果能帮助解决这个问题,我们将不胜感激。 java(动态(手动)注册流的自动配置类) java(所有集成流用于将请求委托给负责业务逻辑实现的Coreflow的公共类) java(处理业务逻辑的类)

  • 为了好玩,我决定用红宝石编码伊拉托西筛子。只是为了好玩,因为我知道有一个库函数。而且,我认为它会很快。但我发现它并不是,至少在我的ruby 1.9.3中,我的上网本速度快了好几倍,甚至在c中也没有。为什么会这样呢。 库实现: 我在红宝石: 图书馆非常慢。

  • 我试图使用Kotlin实现干净的架构。这一过程的流程将是: 代码示例: