2017-09-22 9 views
-4

개체에 LINQ가 결합 된 데이터의 다른 실행을위한 좋은 방법이라고 생각했습니다. 실제로, 그것은 여기 개체에 Linq - boondoggle?

이 상응
IEnumerable<MyModel> data = 
    (from a in AList 
    from b in BList.Where(r => r.AId == a.Id) 
    from c in CList.Where(r => r.BId == b.Id) 
    from d in DList.Where(r => r.SomeId == myId && r.Some2Id == c.Some2Id) 
// . . . . . . 

는 LINQ 아니 었 우리가 a,b,c,d에 몇, 몇 백, 3K 및 3.5K 기록을 가지고 있었다 것입니다 ... 일을하는 나쁜 방법을 제공 그 일을하는 것에 대해 대단하다고 생각하니? 현실에서 는, 다음은 60 배 빠른 사실

var dTemp = DList.Where(r => r.SomeId == myId).ToList(); 
var cTemp = CList.Where(c => dTemp.Any(d => d.Some2Id == c.Some2Id)).ToList(); 

IEnumerable<MyModel> data = 
    (from a in AList 
    from b in BList.Where(r => r.AId == a.Id) 
    from c in cTemp.Where(r => r.BId == b.Id) 
// . . . . . . 

을에, 훨씬 빠르게 작동 그리고 나는 this article

Q 건너 온 : 단일 LINQ를 포기하지 않고이 쿼리를 향상시킬 수있는 방법이 있나요?

또는 성능이 문제가되는 경우 조인 형식의 개체에 대한 LINQ를 피하고 일부 순차적 호출로 대체해야합니다.

+2

은'A','b'와'c'에 가입. ''Join' (https://docs.microsoft.com/en-gb/dotnet/api/system.linq.enumerable.join?view=netframework-4.7) 함수 대신에'where' '에스? – Reddog

+1

LINQ를 덜 공격적으로 생각하십시오. "틀림 없으므로 프레임 워크를 깨뜨려 야합니다."보통 시작하기 가장 좋은 장소는 아닙니다. –

+0

@EdPlunkett하시기 바랍니다. 나는 그것이 부러 졌다고 결코 말하지 않는다. 하지만 옵티 마이저가 필요하기 때문에 보이는 것처럼 보이지 않습니다. –

답변

3

차이점을 분석해 보겠습니다.

첫 번째 쿼리 : 당신이 지연된 실행 방식으로 DList 모두에 CList과 두 개의 필터에 BList에 필터를 필터를 수행하고 있습니다. 그런 다음 일종의 조인을 사용합니다.
두 번째 쿼리 : 당신은 DList에 정적 필터를 수행하고 AListBList 모두에 지연된 실행 필터를 DList에 따라 CList 다른 정적 필터를 평가하고 평가합니다.

  • DList가 (인해 이전 필터로) 쓸모 값에보고되지 않고
  • CList에만 의한 이전 필터

유용한 값을 포함

번째 쿼리 때문에 속도가 어쨌든 두 쿼리가 모두 잘못되었습니다. 복수 from은 기본적으로 cross-join, as explained here입니다. @Reddog은 주석으로, 가장 좋은 방법은 실제로 Join을 사용하는 것입니다 : 당신이 내부에 노력하고 마치

var data = from a in AList 
      join b in BList on a.Id equals b.AId 
      join c in CList on b.Id equals c.BId 
      join d in DList on c.Some2Id equals d.Some2Id 
      where d.SomeId == someId; 
+0

맞습니다. 'from-from' 조건은'from-join'과 동일합니다. 작은 데이터 세트로는 문제가 발생하지 않았습니다. 그러나이 한 명의 클라이언트는 독특한 설정을 가지고있었습니다.이 설정에서는'c'와'd'에 커다란 세트가 있고 너무 잘 수행되지 않았습니다. 그럼에도 불구하고 -140ms는 그렇게 나쁘지는 않았지만 반복적으로 실행되었습니다. 그래서 140x20 ... 이제 2ms입니다. 2x20 - 매우 다른 결과. 이전에 조정할 것이지만 캐시 된 데이터가 교체되고 올바르게 작동하는 SQL 호출에 대해 벤치 마크했습니다.그래서 아무도 작은 LINQ 사실에 관심을 기울이지 않았습니다. 고맙습니다 –