Performance 具有计数的linq组的性能

Performance 具有计数的linq组的性能,performance,linq,entity-framework,group-by,Performance,Linq,Entity Framework,Group By,我有一个使用linq和group by表达式的方法: public List<SerieVu> ListSeriesLesPlusVuesSemaine() { DateTime dateIlYaSeptJours = DateTime.Now.AddDays(-7); var resultat = from uev in Query(uev => uev.userepivu_date > dateIlYaSeptJours) group

我有一个使用linq和group by表达式的方法:

public List<SerieVu> ListSeriesLesPlusVuesSemaine()
{
    DateTime dateIlYaSeptJours = DateTime.Now.AddDays(-7);

    var resultat =
    from uev in Query(uev => uev.userepivu_date > dateIlYaSeptJours)
    group uev by uev.Episode.Saison.Serie into pgroup
    let count = pgroup.Count()
    orderby count descending
    select new SerieVu() { nombreDeVus = count, Serie = pgroup.Key };

    return resultat.Take(7).ToList();
}
我的问题是如何提高此查询的性能?在我的网站的一个非常重要的页面上大约需要6秒钟


感谢您的帮助

您可以先在数据库中创建一些索引 您应该将字段形式where、order by和group by放入索引中 通过在userepivu_日期上创建索引,您可能会获得最大的性能改进,因为此处[Extent1]。[userepivu_日期]>'2013-01-11T09:53:26' 我会扫描你的整个桌子

在SQL Server上创建索引:

CREATE INDEX [indexname] ON Extent1 (userepivu_date)

我应该给出的第一个建议是查看执行计划并搜索瓶颈

那么,为什么会有一个左外连接呢

左外连接[dbo].[Serie]作为[extend4]

它不应该是一个内部连接吗(如果是的话,映射可能会有问题)? 我想它可能会阻止在连接过程的早期执行where子句,从而破坏查询优化

也许您可以尝试运行查询,将左侧外部联接替换为内部联接,看看这是否会有所不同。
另外,请同意@user1802430,如果userepivu_日期上没有索引,您肯定需要放置索引。

我找到了解决方案。我已使用显式联接强制内部联接:

public List<SerieVu> ListSeriesLesPlusVuesSemaine()
{
    DateTime dateIlYaSeptJours = DateTime.Now.AddDays(-7);

    ObjectSet<UtilisateurEpisodeVu> UtilisateurEpisodeVuSet = _context.CreateObjectSet<UtilisateurEpisodeVu>();
    ObjectSet<Episode> EpisodeSet = _context.CreateObjectSet<Episode>();
    ObjectSet<Saison> SaisonSet = _context.CreateObjectSet<Saison>();
    ObjectSet<Serie> SerieSet = _context.CreateObjectSet<Serie>();

    var resultat =
    from uev in UtilisateurEpisodeVuSet.Include("Episode.Saison.Serie").Where(uev => uev.userepivu_date > dateIlYaSeptJours)
    join e in EpisodeSet on uev.episode_id equals e.episode_id
    join sai in SaisonSet on e.saison_id equals sai.saison_id
    join s in SerieSet on sai.serie_id equals s.serie_id
    group uev by s into pgroup
    let count = pgroup.Count()
    orderby count descending
    select new SerieVu() { nombreDeVus = count, Serie = pgroup.Key };

    return resultat.Take(7).ToList();
}
公共列表列表系列lesplusvuessemaine()
{
DateTime dateIlYaSeptJours=DateTime.Now.AddDays(-7);
ObjectSet UsilizateurePiSodeVuset=_context.CreateObjectSet();
ObjectSet情节集=_context.CreateObjectSet();
ObjectSet SaisonSet=_context.CreateObjectSet();
ObjectSet序列集=_context.CreateObjectSet();
结果变量=
来自uev的UsilizateurePiSodeVuser.Include(“插曲.Saison.Serie”)。其中(uev=>uev.userepivu_date>dateIlYaSeptJours)
在uev上的情节集中加入e。插曲id等于e
将sai加入SaisonSet在e.saison_id上等于sai.saison_id
在sai.serie_id上的序列集中加入s等于s.serie_id
将uev按s分组为pgroup
let count=pgroup.count()
orderby计数递减
选择newserievu(){nombreDeVus=count,Serie=pgroup.Key};
return resultat.Take(7.ToList();
}

使用此方法,linq查询仅生成内部联接;)感谢所有试图帮助我的人

非常感谢你的回答。我尝试使用用户内部连接而不是左外部连接,性能非常好:300毫秒。现在我的问题是:如何使用linq做到这一点?因为此SQL查询是由Linq@toregua您必须手动对联接进行编码。显然,
Saison.Serie
不是必填字段,因此EF创建了一个外部联接。@toregua不熟悉EF:您可能必须更改您的模型或代码映射,以便在Saison和Serie之间有一个外键,使其成为1,*关系,而不是0,*。或者添加一个必需的属性,正如GertArnold Bon courageI所建议的,Saison和Serie之间已经存在1,*关系。Saison和Serie之间也存在外键:(似乎是实体框架错误?还是再次感谢您的回答。不幸的是,我已经在相关表THX上建立了索引以供后续操作。如果可以,您应该接受自己的答案。还想知道,如果您有反向关系,您是否可以从另一个方向开始:从se系列中的se开始,从se.saisons中的sa开始。。。其中uev.userepivu_date>dateIlYaSeptJours由uev由se分组到pgroup。。。
public List<SerieVu> ListSeriesLesPlusVuesSemaine()
{
    DateTime dateIlYaSeptJours = DateTime.Now.AddDays(-7);

    ObjectSet<UtilisateurEpisodeVu> UtilisateurEpisodeVuSet = _context.CreateObjectSet<UtilisateurEpisodeVu>();
    ObjectSet<Episode> EpisodeSet = _context.CreateObjectSet<Episode>();
    ObjectSet<Saison> SaisonSet = _context.CreateObjectSet<Saison>();
    ObjectSet<Serie> SerieSet = _context.CreateObjectSet<Serie>();

    var resultat =
    from uev in UtilisateurEpisodeVuSet.Include("Episode.Saison.Serie").Where(uev => uev.userepivu_date > dateIlYaSeptJours)
    join e in EpisodeSet on uev.episode_id equals e.episode_id
    join sai in SaisonSet on e.saison_id equals sai.saison_id
    join s in SerieSet on sai.serie_id equals s.serie_id
    group uev by s into pgroup
    let count = pgroup.Count()
    orderby count descending
    select new SerieVu() { nombreDeVus = count, Serie = pgroup.Key };

    return resultat.Take(7).ToList();
}