2014-04-02 4 views
0

C# 및 Entity Framework를 사용하고 있습니다. 내 제품, 태그 태그 (Id, Name) 및 사용 가능한 모든 태그가 들어있는 Products 테이블 (Id, Name)과 제품에 태그를 할당하는 데 사용되는 ProductTags 테이블 (Id, ProductId, TagId)이 있습니다. 사용자는 여러 태그 (Int[] SelectedTagIds)가있는 제품을 보도록 지정할 수 있습니다. 질문은 : 각 제품이 사용자가 지정한 모든 태그를 가지고있는 모든 제품을 얻는 방법입니다. 이제모든 태그가있는 제품 선택

나는 이것이 올바른 방법이 궁금하거나 더 나은/더 빠른 방법이이 쿼리

`var reault = Context.Products 
        .Where(x => SelectedTagIds.All(y => 
          (x.ProductTags.Select(z => z.TagId)) 
        .Contains(y)));` 

을 사용하고?

+2

실제 성능 문제가 있거나 사전에 최적화를 시도하고 있습니까? –

+0

@Oren 프로젝트가 현재 개발 중이며 db에 3 개의 테스트 태그/10 개의 테스트 태그 만 있기 때문에 advn에서 최적화하려고합니다 ... –

+0

최적화하는 가장 좋은 방법은 이론화를 피하는 것이고 실제로 많은 수의 태그와 제품 및 그 연관성을 유지하는 것입니다 - 향후에 예상하는 것보다 약간 큰 것이 바람직합니다. 그런 다음 다른 방법론이 더 나을지 추측하기보다는 성능이 수용 가능한지 테스트 할 수 있습니다. –

답변

2

intersect를 사용하고 둘의 길이를 확인하면 intersected가 검색 태그와 동일한 개수인지 확인하여 모든 검색 태그가 ProductTags 컬렉션에 있음을 확인할 수 있습니다.

 var result = 
      products.Where(
       x => x.ProductTags.Intersect(searchTags).Count() == searchTags.Length); 

그러나 성능 분석을 실행하면 더 효과적입니다. 그러나 Oren이 언급 한 바와 같이 실제로 성능 문제가 있습니까? 이러한 콜렉션 모두가 매우 작기 때문에 병목 현상이 발생하지 않을 것입니다.

편집 : 단지의 집합, 교차의 성능, 그것은, .Contains 내 컴퓨터에

를 성능과 .ALL를 사용하는 것보다 느린 1,000 결과 쿼리를 작성하고 ToList()를 사용하여 열거를 확인

searchTags.All(search => x.ProductTags.Contains(search)) = 202ms

!searchTags.Except(x.ProductTags).Any() = 339ms

: 2 검색 태그 1000 개 제품은 나에게 한 아래와 같은 성능을 제공합니다 다음을 사용하여 HashSets 비교

실행 hashsets를 사용하여 비교 가지고 : 당신이 정말로 성능을 향상해야하는 경우3210 x.ProductTags.Intersect(searchTags).Count() == searchTags.Length = 389ms

, 당신은 당신의 ProductTags 및 SelectedTagIds

EDIT 2 HashSet에 사용할 수 1000 개의 쿼리 개체를 생성하고 ToList()를 사용하여 목록으로 실행하면 결과는 다음과 같습니다.

List<Tag>당신이 볼 수 있듯이 HashSet<Tag>

Creating Events took 26ms 
Number of Tags = 3000 
Number of Products = 1003 
Average Number of Tags per Products = 100 
Number of Search Tags = 10 

.All.Contains = 259ms - Found 51 
.Intersect = 6417ms - Found 51 
.Except = 7347ms - Found 51 

사용는

Creating Events took 6ms 
Number of Tags = 3000 
Number of Products = 1003 
Average Number of Tags per Products = 100 
Number of Search Tags = 10 

.All.Contains = 5379ms - Found 51 
.Intersect = 5823ms - Found 51 
.Except = 6720ms - Found 51 

, HashSet의를 사용하여 당신이 HashSets을 만들 여분이 20ms 감안하더라도 상당히 빠릅니다. 해시는 ID 필드의 간단한 해시 였지만 당신이 더 복잡한 해시 결과를 사용한다면 다른 결과가 나옵니다.

관련 문제