我的EF查询速度非常慢。我该怎么调试呢?

时间:2014-01-21 12:27:43

标签: asp.net asp.net-mvc entity-framework entity-framework-6

我有以下由EF6和SQL Server 2012数据库备份的类。问题表中有大约500条记录,问题表中有250条记录,副主题表中有20条记录:

public class Question
{
    public int QuestionId { get; set; }
    public int ProblemId { get; set; }
    public int QuestionStatusId { get; set; }
    public string Text { get; set; }
    public string AssignedTo { get; set; }
    public DateTime AssignedDate { get; set; }
    public int QuestionTypeId { get; set; }
    public virtual Problem Problem { get; set; }
    public virtual QuestionStatus QuestionStatus { get; set; }
    public virtual QuestionType QuestionType { get; set; }
}
public class Problem
{
    public Problem()
    {
        this.Questions = new List<Question>();
    }
    public int ProblemId { get; set; }
    public int SubTopicId { get; set; }
    public string Text { get; set; }
    public virtual SubTopic SubTopic { get; set; }
    public virtual ICollection<Question> Questions { get; set; }
}
public partial class SubTopic
{
    public SubTopic()
    {;
        this.Problems = new List<Problem>();
    }
    public int SubTopicId { get; set; }
    public int Number { get; set; }
    public int TopicId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Problem> Problems { get; set; }
    public virtual Topic Topic { get; set; }
}

我设置了以下地图:

    public ProblemMap()
    {
        // Primary Key
        this.HasKey(t => t.ProblemId);
        this.HasRequired(t => t.SubTopic)
            .WithMany(t => t.Problems)
            .HasForeignKey(d => d.SubTopicId)
            .WillCascadeOnDelete(false);
    }
    public QuestionMap()
    {
        // Primary Key
        this.HasKey(t => t.QuestionId);
        // Relationships
        this.HasRequired(t => t.Problem)
            .WithMany(t => t.Questions)
            .HasForeignKey(d => d.ProblemId);
        this.HasRequired(t => t.QuestionStatus)
            .WithMany(t => t.Questions)
            .HasForeignKey(d => d.QuestionStatusId);
        this.HasRequired(t => t.QuestionType)
            .WithMany(t => t.Questions)
            .HasForeignKey(d => d.QuestionTypeId);
    }
    public SubTopicMap()
    {
        // Primary Key
        this.HasKey(t => t.SubTopicId);
        // Relationships
        this.HasRequired(t => t.Topic)
            .WithMany(t => t.SubTopics)
            .HasForeignKey(d => d.TopicId);
    }

我正在尝试对这些看起来像这样的查询:

IList<Question> questions;
questions = _questionsRepository
    .GetAll()
    .Where(q => q.Problem.SubTopic.TopicId == topicId || topicId == 0)
    .Where(q => q.QuestionStatusId == questionStatusId || questionStatusId == 0)
    .Where(q => q.AssignedTo == assignedTo || assignedTo == "0")
    .Where(q => q.ModifiedBy == modifiedBy || modifiedBy == "0")
    .Include(q => q.Problem)
    .Include(q => q.Answers)
    .ToList();

问题是查询开始但似乎永远不会返回。有什么我做错了吗?有没有办法可以找出它试图对数据库执行什么样的查询?

可能是以下情况导致事情进展缓慢:

    q.Problem.SubTopic.TopicId == topicId

这是存储库GetAll()

    public virtual IQueryable<T> GetAll()
    {
        return DbSet;
    }

2 个答案:

答案 0 :(得分:2)

您可以使用Linq to Entity query visualizer

这是Visual Studio的免费扩展。说明:

  

在Visual Studio 2008/2010 /中进行调试时,将LInQ的本机SQL(MS SQL,DB2,Oracle等)查看到实体ObjectQuery。还可以查看Lambda表达式,编辑查询参数,查看数据库连接信息,查看查询结果以及将结果导出到MS Excel(无需MS Excel)

然后,您可以复制查询并在需要时将其粘贴到SQL Server中。

您也可以使用LinqPad。此应用程序允许您编写针对不同数据库后端和LINQ的不同风格的测试LINQ表达式:LINQ to SQL,LINQ to Entities,LINQ to Objects ...

最后,free version of DevArt LINQ Insight (express versions)。它也是一个VS扩展。

答案 1 :(得分:0)

我认为这个查询根本不起作用。在问题和问题以及问题和子主题之间没有连接。如果使用连接重写查询,我认为没有理由不能正常执行。

尝试这样的事情:

from q in db.Questions
join p in db.Problems on q.ProblemId equals p.ProblemId
join s in db.SubTopics on s.SubTopicId equals p.SubTopicId
where q.QuestionStatusId == questionStatusId &&
q.AssignedTo == assignedTo
q.ModifiedBy == modifiedBy
s.TopicId == topicId
select q

为了调试,我使用SQL Profiler。从SQL事件探查器获得查询后,您可以使用数据库引擎优化顾问来查看数据库中是否缺少索引。