Mysql 如何优化实体框架查询

Mysql 如何优化实体框架查询,mysql,performance,entity-framework,Mysql,Performance,Entity Framework,我正在使用LINQtoEntities执行一个查询,该查询只返回947行,但运行需要18秒。我做了一个“ToTraceString”来获取底层sql,并直接在数据库上运行相同的东西,获得相同的时间 我使用了tuning advisor并创建了几个索引,但影响不大 查看查询执行计划,有两个嵌套循环占用了95%的时间,但它们已经在索引上工作了 有人对如何在EF查询中强制进行一些优化有什么想法吗 编辑:提供附加信息 三个表的基本ER图如下所示: People >----People_Event_

我正在使用LINQtoEntities执行一个查询,该查询只返回947行,但运行需要18秒。我做了一个“ToTraceString”来获取底层sql,并直接在数据库上运行相同的东西,获得相同的时间

我使用了tuning advisor并创建了几个索引,但影响不大

查看查询执行计划,有两个嵌套循环占用了95%的时间,但它们已经在索引上工作了

有人对如何在EF查询中强制进行一些优化有什么想法吗

编辑:提供附加信息

三个表的基本ER图如下所示:

People >----People_Event_Link ----< Events
P_ID        P_ID                    E_ID
            E_ID
下面是生成的SQL(深呼吸!):


对。重写LINQ查询。大多数LINQtoEntities查询可以用多种不同的方式编写,并以不同的方式转换为SQL。因为您既没有显示LINQ,也没有显示SQL,也没有显示查询计划,所以我只能说这些

但是,您可以尝试直接执行SQL。查询编译也可能需要时间,但您已经通过确定SQL占用了所有测量的时间来排除了这一点

尝试:

或者如果pe.事件是一对一:

    var query = from pe in genesisContext.People_Event_Link
                where pe.P_ID == key
                select pe.Event;

    return query;

由于95%的时间在嵌套循环中,消除它们应该可以解决问题

有几件事你可以看看:

  • 是否需要嵌套循环。如果直接在SQL中编写查询,那么不使用嵌套循环也可以得到相同的结果。如果答案是可以在没有嵌套循环的情况下编写,那么模型或linq查询中是什么导致了它

  • 您可以选择在视图中放置一些逻辑,从而降低linq查询的复杂性,并且可能不再需要嵌套循环

通常我使用SQLServer探查器来查看SQLLINQ生成的内容,我发现这更容易,尤其是如果您有两个屏幕

如果您仍然有问题,请发布您的linq查询。

@Craig
我无法使您的查询工作,因为我收到一条错误消息,说在调用SelectMany时类型推断失败

但是,我采纳了您的建议,从使用联接改为使用“旧样式”的前ANSI类型查询:

        var query = from pe in genesisContext.People_Event_Link
                    from ev in genesisContext.Events
                    where pe.P_ID == key && pe.Event == ev
                    select ev;

这就产生了相当不错的sql

我已经看过linq查询了,但老实说,它没有太多需要更改的地方(见上文)!在LINQ to实体中使用join几乎是不正确的。人员\事件\链接的事件上的属性名称是什么(换句话说,pe.Event的另一端?我会在我的答案中做一个猜测;如果我错了,请纠正我。我刚刚建立了自己的sql来执行查询,它在不到一秒钟的时间内运行良好,sheesh….从事件中选择*作为E.E_ID上的E.E_ID=pe.E_ID内部连接人作为P.P_ID=pe.P_ID,其中P_ID=291。)“调用SelectMany时类型推断失败”意味着我对属性名的猜测是错误的。但是您已经有了一个大致的想法——要获得不同的SQL,请尝试不同的LINQ。
    var query = from pe in genesisContext.People_Event_Link
                where pe.P_ID == key
                from ev in pe.Event // presuming one to many
                select ev;
    var query = from pe in genesisContext.People_Event_Link
                where pe.P_ID == key
                select pe.Event;

    return query;
        var query = from pe in genesisContext.People_Event_Link
                    from ev in genesisContext.Events
                    where pe.P_ID == key && pe.Event == ev
                    select ev;