我正在使用Entity Framework 4(首先是数据库)开发电影数据库应用程序,并且需要30秒才能将大约8,200行加载到列表中。涉及三个表,当我使用.include()时,性能会进一步下降-差不多三分钟才能加载8,200行。真痛苦鉴于我一次要学习很多技术,所以希望有一个简单的修复方法。详细信息如下:

表1-视频

这是一个大表,有31列,约有7800行视频。它使用Guid作为其主键。

表2-ActorVideos(联结表)

该表具有两列:(1)VideoID列和(2)ActorID列。两列都是Guid,分别是Video和Actor表的外键。该表使用复合主键,其中两列均充当主键。 EF4不对该表进行建模;但是,它会创建一个导航属性。该表允许用户为电影分配任意数量的演员。

表3-演员

有16列,大约有400行。同样,主键是Guid。

在代码中,我正在读取“视频”表中的约10列,然后从关联的“演员”表中读取了列。

C#代码如下所示:

var videos = context.Videos
foreach (var video in videos)
{
    // retrieve 10 or so properties from 'video'

    if (video.Actors.Count > 0)
    {
        foreach (var actor in video.Actors)
        {
            // retrieve some properties on the actor
        }
    }
}


我尝试在context.video之后添加.include(“ Actors”),如上所述,性能从糟糕到恐怖。

我看了用Include生成的SQL,考虑到视频表中的列数,它大约是2K的文本。

我是否必须使用“主/细节”模式拆分视频表?我的下一步是缓存actor表,并完全避免导航/关联属性。还有其他建议可以加快速度吗?我认为它应该在5-6秒内运行。

编辑:数据库是SQL Server CE 3.5。

最佳答案

您要让Entity Framework加载视频及其所有参与者,然后在应用程序代码中进行过滤。通常,您将获取比所需更多的数据。我将为您准备SQL Server(或您使用的任何数据库)预过滤器:

var videos = context.Videos;
var results = from video in videos
              where video.Actors.count > 10
              group video.Actors by video.VideoID into grouping
          select new
          {
              video.VideoID,
              video.Actors
          };

foreach (var group in results)
{
    foreach (var actor in group.Actors)
    {
        // do stuff
    }
}


在视频表中加载约8200行及其关联的行应该非常快。我在工作中做了一些开发,必须处理5个表联接的70+百万行测试数据表。大概半分钟就到了。

但是,它运行的速度比您执行的速度快得多的原因是因为我正在SQL Server内部进行过滤。使用EF的等效“过程”程序花费了几分钟,因为我在从数据库中提取行之后进行了过滤。

这样想:您不仅要查询数据库中的每一行,而且要提取甚至不需要多次的数据。

07-26 09:34
查看更多