2008-11-25 2 views
1

이 쿼리는 LINQ to Entities에 있습니다.LINQ to Entities에서 그룹 기반 최적화

 var query = (from s in db.ForumStatsSet 
        where s.LogDate >= date1 && s.LogDate <= date2 
        group s by new { s.Topic.topicID, s.Topic.subject, s.Topic.Forum.forumName, s.Topic.datum, s.Topic.Forum.ForumGroup.name, s.Topic.Forum.forumID } into g 
        orderby g.Count() descending 
        select new TopicStatsData 
        { 
         TopicId = g.Key.topicID, 
         Count = g.Count(), 
         Subject = g.Key.subject, 
         ForumGroupName = g.Key.name, 
         ForumName = g.Key.forumName, 
         ForumId = g.Key.forumID 
        }); 

나는 "일종의"쿼리라고 알고 있지만 관리 인터페이스에서만 사용됩니다. 그러나 생성 된 SQL은 절대적으로 끔찍합니다. 이 아기 좀 봐.


exec sp_executesql N'SELECT TOP (50) 
[Project6].[C1] AS [C1], 
[Project6].[TopicId] AS [TopicId], 
[Project6].[C4] AS [C2], 
[Project6].[subject] AS [subject], 
[Project6].[name] AS [name], 
[Project6].[forumName] AS [forumName], 
[Project6].[C2] AS [C3] 
FROM (SELECT 
    [Project5].[TopicId] AS [TopicId], 
    [Project5].[subject] AS [subject], 
    [Project5].[forumName] AS [forumName], 
    [Project5].[name] AS [name], 
    1 AS [C1], 
    CAST([Project5].[forumID] AS int) AS [C2], 
    [Project5].[C1] AS [C3], 
    [Project5].[C2] AS [C4] 
    FROM (SELECT 
     [Project4].[TopicId] AS [TopicId], 
     [Project4].[forumID] AS [forumID], 
     [Project4].[subject] AS [subject], 
     [Project4].[forumName] AS [forumName], 
     [Project4].[name] AS [name], 
     [Project4].[C1] AS [C1], 
     (SELECT 
      COUNT(cast(1 as bit)) AS [A1] 
      FROM  [dbo].[tForumStats] AS [Extent14] 
      LEFT OUTER JOIN [dbo].[tTopic] AS [Extent15] ON [Extent14].[TopicId] = [Extent15].[topicID] 
      LEFT OUTER JOIN [dbo].[tForum] AS [Extent16] ON [Extent15].[forumID] = [Extent16].[forumID] 
      LEFT OUTER JOIN [dbo].[tForum] AS [Extent17] ON [Extent15].[forumID] = [Extent17].[forumID] 
      LEFT OUTER JOIN [dbo].[tForum] AS [Extent18] ON [Extent15].[forumID] = [Extent18].[forumID] 
      LEFT OUTER JOIN [dbo].[tForumGroup] AS [Extent19] ON [Extent18].[forumGroupID] = [Extent19].[forumGroupID] 
      LEFT OUTER JOIN [dbo].[tForum] AS [Extent20] ON [Extent15].[forumID] = [Extent20].[forumID] 
      LEFT OUTER JOIN [dbo].[tForumGroup] AS [Extent21] ON [Extent20].[forumGroupID] = [Extent21].[forumGroupID] 
      WHERE ([Extent14].[LogDate] >= @p__linq__25) AND ([Extent14].[LogDate] = @p__linq__25) AND ([Extent6].[LogDate] = @p__linq__25) AND ([Extent1].[LogDate]

는 그 쿼리를 설명하는 사람으로하지 않습니다하지만이 단순한 일반 가입 할 수 있도록 쿼리를 optimze하는 방법에 대한 몇 가지 도움말을 얻을 좋은 것입니다. SQL을 직접 작성하면 이처럼 작동합니다.

SELECT COUNT(*) AS NumberOfViews, s.topicid AS topicId, t.subject AS TopicSubject, g.[name] AS ForumGroupName, f.forumName AS ForumName 
FROM tForumStats s 
join tTopic t on s.topicid = t.topicid 
join tForum f on f.forumid = t.forumid 
JOIN tForumGroup g ON f.forumGroupID = g.forumGroupID 
WHERE s.[LogDate] between @date1 AND @date2 
group by s.topicid, t.subject, f.Forumname, t.Datum, g.[name] 
order by count(*) desc 

Btw,이 사이트를 사랑합니다. 놀라운 디자인과 유용성! 그것이 도움이 잘 작동하기를 바랍니다 :)

+0

희망, 큰 쿼리를 잘라 부 Linq가 entites에 생성 된 것처럼 보이지만, 나는 당신을 비난하지 않습니다. 제 생각에는 당신이 생각한 것 같아요. – Olaj

답변

5

그룹에 속한 모든 테이블을 합류하는 대신 지정된 테이블에 직접 참여할 수 있습니다. 이것을 시도해 볼 수 있습니까?

from s in db.ForumStatsSet 
join t in db.Topics on t.TopicId == s.TopicId 
join f in db.Forums on f.ForumId == t.ForumId 
join fg in db.ForumGroups on fg.ForumGroupId == f.ForumGroupId 
where s.LogDate >= date1 && s.LogDate <= 
group s by new { t.TopicId, t.subject, f.forumName, t.datum, fg.name, f.forumID } into g 
orderby g.Count() descending 
select new TopicStatsData 
{ 
TopicId = g.Key.topicID, 
Count = g.Count(), 
Subject = g.Key.subject, 
ForumGroupName = g.Key.name, 
ForumName = g.Key.forumName, 
ForumId = g.Key.forumID 
}); 

ps : 논리적으로는 정확하지만 정확해야합니다.

+0

고마워, 나는 할 수 없어. 이전 LINQ to SQL 방식을 사용하여 과 같은 절에서 여러 항목을 db.ForumStatsSet의에서 가져 오십시오. Doesnt는 작동하며 "제거 된"이후에 조인을 수행 할 ID가 없습니다. 모델을 .. 음 .. 혼란 스럽군 .. – Olaj

+0

지금 해결, 내가 잘못된 순서로 조인했다 .. – Olaj

0

나는 문제가 그룹화 구조와 생각합니다. 데이터를 먼저 추출한 다음 (속성을 거치지 않아도 됨) 추출 된 데이터로 그룹화하십시오.

IOW, SQL에 대해 LINQ like를 써보십시오.