Linq можно ли оптимизировать эти подзапросы? - PullRequest
0 голосов
/ 15 апреля 2011

Этот запрос принимает группу комментариев, затем подсчитывает их положительные и отрицательные голоса в таблице tblCommentVotes.

В данный момент он подсчитывает их с помощью оператора select new в форме подзапроса.Было бы это более эффективно, если бы он был в какой-то группе в основном запросе?Кроме того, если бы это было так, мог бы кто-нибудь показать мне, как это сделать, поскольку я не могу понять, как вы это сделаете.

// Get comments
var q = (
    from C in db.tblComments
    where
        C.CategoryID == Category &&
        C.IdentifierID == Identifier
    join A in db.tblForumAuthors on C.UserID equals A.Author_ID
    orderby C.PostDate descending
    select new
    {
        C,
        A.Username,
        UpVotes = (from V in db.tblCommentVotes where V.CommentID == C.ID && V.UpVote == true select new { V.ID }).Count(),
        DownVotes = (from V in db.tblCommentVotes where V.CommentID == C.ID && V.UpVote == false select new { V.ID }).Count()
    }
)
.Skip(ToSkip > 0 ? ToSkip : 0)
.Take(ToTake > 0 ? ToTake : int.MaxValue);

Ответы [ 4 ]

3 голосов
/ 15 апреля 2011

Что вам нужно сделать, это выполнить левое внешнее объединение db.tblCommentVotes в выражении запроса, потому что, возможно, там нет комментариевVotes?

Если у вас есть это, вы сможете выполнить ОДИН запрос, чтобы получить свой результат.

Это может выглядеть так:

var q = (
   from C in db.tblComments
   where
      C.CategoryID == Category &&
      C.IdentifierID == Identifier
   join A in db.tblForumAuthors on C.UserID equals A.Author_ID
   // the following two lines are the left outer join thing. 
   join voteTemp in db.tblCommentVotes on voteTemp.CommentID equals C.ID into voteJoin
   from vote in voteJoin.DefaultIfEmpty()
   orderby C.PostDate descending
   group C by new { Comment = C, Username = A.Username } into g
   select new
   {
      g.Key.Comment,
      g.Key.Username,
      UpVotes = g.Count(x => x.UpVote),
      DownVotes = g.Count(x => !x.UpVote)
   }
)
.Skip(ToSkip > 0 ? ToSkip : 0)
.Take(ToTake > 0 ? ToTake : int.MaxValue);

Это не проверено и может даже не скомпилироваться, но я думаю, что должно быть что-то вроде этого.

1 голос
/ 15 апреля 2011

Для оптимизации лучше сначала измерить.

  • Попробуйте использовать что-то вроде LinqPad для просмотра сгенерированного SQL
  • Затем используйте SQL Server Management Studio для просмотра плана запроса для этогоSQL

или:

  • Попробуйте запустить код и посмотреть, что происходит с трассировкой SQL

Без БД это довольно сложно(но забавно) угадать, приведет ли этот Linq к одному или нескольким запросам для выработки UpVotes и DownVotes.Моя догадка состоит в том, что вычисление UpVotes и DownVotes таким способом может быть довольно дорогим - это может привести к 2 дополнительным запросам на комментарий.

1 голос
/ 15 апреля 2011
db.tblComments.Where(c => c.CategoryID == Category && c.IdentifierID == Identifier)
              .Join(db.tblForumAuthors, c => c.UserID, a => a.Author_ID,
                     (c, a) =>
                     new
                     {
                        CommentID = c,
                        AuthorName = a.UserName,
                        UpVotes = c.Join(db.tblCommentVotes, c => c.CommentID
                                                             v => v.CommentID,
                                                             (c, v) => v).Count(v => v.UpVote)
                        DownVotes = c.Join(db.tblCommentVotes, c => c.CommentID
                                                              v => v.CommentID,
                                                              (c, v) => v).Count(v => v.DownVote)
                     });
0 голосов
/ 15 апреля 2011

http://www.thereforesystems.com/view-query-generate-by-linq-to-sql/

без анализа того, что выводится, на этот вопрос невозможно ответить ... однако приведенная выше ссылка должна дать вам инструменты, необходимые для выполнения этого анализа самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...