【问题标题】:Linq to SQL one to many relationshipsLinq to SQL 一对多关系
【发布时间】:2012-10-07 16:19:17
【问题描述】:

过去几天我一直在为 linq 查询性能苦苦挣扎:

LinqConnectionDataContext context = new LinqConnectionDataContext();
System.Data.Linq.DataLoadOptions options = new System.Data.Linq.DataLoadOptions();
options.LoadWith<Question>(x => x.Answers);
options.LoadWith<Question>(x => x.QuestionVotes);
options.LoadWith<Answer>(x => x.AnswerVotes);
context.LoadOptions = options;
var query =( from c in context.Questions
            where c.UidUser == userGuid
            && c.Answers.Any() == true
            select new
            {
                c.Uid,
                c.Content,
                c.UidUser,
                QuestionVote = from qv in c.QuestionVotes where qv.UidQuestion == c.Uid && qv.UidUser == userGuid select new {qv.UidQuestion, qv.UidUser },
                Answer = from d in c.Answers
                         where d.UidQuestion == c.Uid
                         select new
                         {
                             d.Uid,
                             d.UidUser,
                             d.Conetent,
                             AnswerVote = from av in d.AnswerVotes where av.UidAnswer == d.Uid && av.UidUser == userGuid select new { av.UidAnswer, av.UidUser }
                         }
            }).ToList();

查询必须运行 5000 行,最多需要 1 分钟。如何提高此查询的性能?

更新:

【问题讨论】:

  • 存储过程?您在 SQL 端用于 JOIN 和 WHERE 子句的列的索引?
  • 用表格图片更新我的问题

标签: c# sql performance linq linq-to-sql


【解决方案1】:

让你开始的东西。

CREATE PROCEDURE GetQuestionsAndAnswers
(
    @UserGuid VARCHAR(100)
)
AS
BEGIN

SELECT 
c.Uid, 
c.Content, 
c.UidUser, 
qv.UidQuestion, 
qv.UidUser, 
av.UidAnswer, 
av.UidUser, 
av.Content,
d.Uid,
d.UidUser,
d.Content
FROM Question c
INNER JOIN QuestionVotes qv ON qv.UidQuestion = c.Uid AND qv.UidUser = @UserGuid
INNER JOIN Answers d ON d.UidQuestion = c.Uid
INNER JOIN AnswerVotes av ON av.UidAnswer = d.Uid AND av.UidUser = @UserGuid
WHERE c.UidUser = @UserGuid

END

默认情况下,您已经在主列上拥有聚集索引(只需在数据库端确认这一点),并且您希望在 QuestionVote - UidUser 列、AnswerVote - UidUser 列和 Answer - UidQuestion 列上使用非聚集索引。

也看看这里。您可能希望使用.AsQueryable() 而不是ToList() 来延迟执行

Do you ToList()?

【讨论】:

  • 哦.. snap...这个存储的精确度的问题是它创建了内部连接,但我所拥有的是:Question 和 QuestionVotes 具有一对多的关系,与 Answer 和 AnswerVote 相同
  • 那么就可以在question.uid、answer.uid上使用group by子句
【解决方案2】:

使用sql-debug-visualizer检查生成的sql,然后复制生成的SQL并从SQL客户端运行它,看看它需要多少时间。如果需要将近 1 分钟,您需要通过添加索引和/或存储过程或创建视图等来提高 DB 级别的性能。

如果上面不需要太多时间,您可以随时创建Stored Procedure and call that using LINQ to SQL。

还有一个建议是使用实体框架if you can change to because 这是未来。

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 2020-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 2011-04-12
    • 1970-01-01
    相关资源
    最近更新 更多