2012-07-21 2 views
4

Article에 많은 양의 열이 있고 데이터베이스에 100,000 개가 넘는 행이 들어 있다고 가정 해 보겠습니다. var articles = db.Articles.ToList()과 같은 작업을 수행하면 데이터베이스의 각 기사에 대한 전체 기사 모델을 검색하고이를 메모리에 보유하고 있습니까?Entity Framework 효율적인 쿼리

엔트리의 날짜와 제목 만 표시하는 테이블을 채우는 경우 은 엔티티 프레임 워크를 사용하여 데이터베이스에서 이러한 열만 검색하며보다 효율적입니까? this에 따르면

,

객체 맥락에서 반환 된 객체를 추적하는 데 필요한 비용이있다. 객체에 대한 변경을 감지하고 같은 논리 객체에 대한 요청이 동일한 객체 인스턴스를 반환하도록 보장 은 객체가 ObjectContext 인스턴스에 연결되어야합니다. 개체를 업데이트하거나 삭제하려고하지 않고 ID 관리가 필요하지 않은 경우 쿼리를 실행할 때 NoTracking 병합 옵션을 사용하는 것이 좋습니다.

데이터가 변경되거나 삭제되지 않고 NoTracking으로 표시되어야합니다. 이제 내 쿼리는 var articles = db.Articles.AsNoTracking().ToList()이됩니다. 더 효율적으로하기 위해해야 ​​할 다른 일이 있습니까?

또 다른 질문은 this answer에 따르면 .Contains(...)을 사용하면 큰 데이터베이스를 다룰 때 큰 성능 저하가 발생합니다. 대형 데이터베이스의 항목을 검색하는 데 사용하는 권장 방법은 무엇입니까?

+0

BTW : 데이터베이스 테이블이 크기 때문에 '포함'이 느리지 않습니다. 'Contains'는 다음과 같이 묻습니다 : "PropertyXValue = 1 또는 PropertyXValue = 5 또는 PropertyXValue = 7 등등이있는 엔티티를주세요. *"Contains "는 요청하는"OR 값 " 크다. 그런 다음 작은 테이블의 경우에도 빈 테이블의 경우에도 속도가 느립니다. – Slauma

답변

4

그것은 투사라고 그냥 SQL에 SELECT column1, column2, ...로 번역 것 :

var result = db.Articles 
    .Select(a => new 
    { 
     Date = a.Date, 
     Title = a.Title 
    }) 
    .ToList(); 

대신 a => new { ... } "당신은 또한라는 이름의 헬퍼 클래스를 사용할 수 있습니다 ("익명 "개체의 목록을 생성) (또는 보기 모델 ") : a => new MyViewModel { ... } (선택한 속성 만 포함하지만 엔터티 자체로는 a => new Article { ... }을 사용할 수 없음).

투영 된 데이터가 어쨌든 추적되지 않기 때문에 AsNoTracking()이 필요하지 않으며 전체 엔터티 개체 만 추적됩니다. 이것은 올해보다 나이가 아닌 경우에만 기사를 선택할 것

var date = DateTime.Now.AddYears(-1); 
var result = db.Articles 
    .Where(a => date <= a.Date) 
    .Select(a => new 
    { 
     Date = a.Date, 
     Title = a.Title 
    }) 
    .ToList(); 

대신 Contains 더 일반적인 방법을 사용

처럼 Where를 사용하는 것입니다. Where은 SQL WHERE 문으로 변환되고 필터는 데이터베이스에서 수행됩니다 (SQL 크기가 테이블 크기와 적절한 인덱싱 등에 따라 빠름). 이 필터의 결과 만 메모리에로드됩니다. 아래 댓글에 다스 려 편집

:

string.Contains(string subString)IEnumerable<T>.Contains(T t)을 혼동하지 마십시오.질문에 링크 된 답변은 Contains의 첫 번째 버전에 대해 이야기합니다.

string keyword = "Entity Framework"; 
var result = db.Articles 
    .Where(a => a.Body.Contains(keyword)) 
    .Select(a => new 
    { 
     Date = a.Date, 
     Title = a.Title 
    }) 
    .ToList(); 

이 SQL에서 WHERE Body like N'%Entity Framework%' 같은로 번역됩니다 : 당신은 텍스트 본문에있는 문자열 "keyword"이 문서를 검색 할 경우 두 번째 Contains 버전이 필요합니다. Contains의 성능 저하에 대한 대답은이 버전의 Contains에는 전혀 적용되지 않습니다.

+0

대부분의 경우'Where'를 사용합니다. 그러나 본문에 '키워드'가있는 기사를 찾으려면'.Contains'가 검색하는 가장 좋은 방법입니까? 또한 당신의 예제에서'.Where (a => date <= a.Date) '는'.Where (a => a.Date> = date)'가 아니거나 중요합니까? –

+0

@GarrettFogerlie : '내용'정보는 위의 편집을 참조하십시오. 그러나 키워드에 대한 쿼리가 많으면 "전체 텍스트 검색"기능이 더 나은 솔루션 일 수 있습니다. 'date <= a.Date' 또는'a.Date> = date'의 경우에는 상관 없습니다. 동일한 결과를 얻을 것입니다. – Slauma