2009-12-16 4 views
0

내가 사용하는 랜덤 Linq2SQL 결과 정렬 구현하기 위해 다음무작위 Linq2SQl 쿼리

partial class OffertaDataContext 
    { 
     [Function(Name = "NEWID", IsComposable = true)] 
     public Guid Random() 
     { 
      throw new NotImplementedException(); 
     } 
    } 

다음 쿼리에서 :

IEnumerable<Enquirys> visibleOnSite = Enquirys.Where(e => 
    e.EnquiryPublished != null && 
    e.Status != 0 && 
    e.Status != 3 && 
    e.Status != 4 && 
    e.Status != 5 
); 

var linq = (
      from e in db.EnquiryAreas 
      from w in db.WorkTypes 
      where 
      e.SeoPriority != 0 && 
      e.HumanId != null && 
      w.SeoPriority != 0 && 
      e.HumanId != null && 
      e.SeoPriority * w.SeoPriority > 20 && 
      visibleOnSite.Any(f => f.WhereId == e.Id && f.WhatId == w.Id) 
      select new 
      { 
       HWhereId = e.Id, 
       WhereDescription = e.DescriptionText, 
       HWhatId = e.Id, 
       WhatDescription = e.DescriptionText 
      } 
     ).OrderBy(e => db.Random()).Take(14); 

나는 SQL 결과에 문제가를 :

SELECT [t3].[Id] AS [HWhereId], [t3].[DescriptionText] AS [WhereDescription], [t3].[Id2] AS [HWhatId], [t3].[DescriptionText2] AS [WhatDescription] 
FROM (
    SELECT TOP (7) [t0].[Id], [t0].[DescriptionText], [t1].[Id] AS [Id2], [t1].[DescriptionText] AS [DescriptionText2] 
    FROM [dbo].[EnquiryAreas] AS [t0], [dbo].[WorkTypes] AS [t1] 
    WHERE ([t0].[SeoPriority] <> 0) AND ([t0].[HumanId] IS NOT NULL) AND ([t1].[SeoPriority] <> 0) AND ([t0].[HumanId] IS NOT NULL) AND (([t0].[SeoPriority] * [t1].[SeoPriority]) > 20) AND (EXISTS(
     SELECT NULL AS [EMPTY] 
     FROM [dbo].[Enquirys] AS [t2] 
     WHERE ([t2].[EnquiryPlace] = ([t0].[Id])) AND ([t2].[EnquiryWorkType] = ([t1].[Id])) AND ([t2].[EnquiryPublished] IS NOT NULL) AND ([t2].[Status] <> 0) AND ([t2].[Status] <> 3) AND ([t2].[Status] <> 4) AND ([t2].[Status] <> 5) 
     )) 
    ORDER BY NEWID() 
    ) AS [t3] 
ORDER BY NEWID() 

내부 ORDER BY NEWID()를 제거하면 모든 것이 잘 작동합니다. 두 가지 모두를 사용하면 쿼리를 완료하는 데 너무 오래 걸립니다. 내 Linq2SQL을 수정하여 외부 ORDER BY NEWID() 만 수행 할 수있는 방법이 있습니까? 그렇지 않은 경우 다른 해결 방법은 무엇입니까? 무작위로 구현하는 다른 방법은?

+1

나는 다른 결과를 얻으 려 할 때 내적 질서를 제거 할 때 모든 것이 잘되지 않는다고 제안합니다. 당신이 선택에서 상위 #을 사용하는 경우 주문을 필요로하거나 결과가 실행마다 일관성이 없습니다. 반면에, 나는 이것이 파생 된 테이블이 될 이유가 전혀 없다고 봅니다. – HLGEM

답변

0

모두는 데이터를 얼마나 무작위로 원 하느냐에 달려 있습니다. 의사 무작위 결과가 허용 가능한 경우 SELECT의 TABLESAMPLE 옵션을 사용할 수 있습니다 (Limiting Result Sets by Using TABLESAMPLE 참조). MSDN의 링크를 읽으십시오. TABLESAMPEL 주변의 몇 가지 제한 사항을 설명합니다. 특히 JOIN과 함께 사용할 때주의해야합니다.

진정한 무작위 표본이 필요한 경우 ORDER BY NEWID()에 대한 대안이 있습니다. 약간 더 나은 솔루션은 각 행에서 평가를 강제로 행 의존 스칼라와 함께, WHERE 절에 NEWID()를 사용하는 것입니다 : 이것은 테이블을 정렬하지 않습니다

SELECT * FROM ... 
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), ID) & 0x7fffffff AS float) 

,하지만 여전히 prety 무거운 스캔을 수행 . LINQ 페이징을 던져라. 그러면 ORDER BY보다 훨씬 좋아질 것이다.

어느 해법도 용인 할 수 없다면, 이번에는 관계형 대수학 101에 대해 더 잘 이해하면서 요구 사항을 다시 한번 살펴보아야 할 것입니다. 관계, 튜플 및 키의 개념을 잘 파악한 후에 자연스러운 푸시 다시 '임의의 관계'에 대한 아이디어는 당신의 문제를 해결할 것입니다 ...