2009-11-23 4 views
1

Linq에서 Entities로 실행되는이 쿼리가 있습니다. 처음 쿼리를 실행하면 2 분 이내에 실행 계획이 생성됩니다. 계획이 캐시 된 후 조회에는 1 ~ 2 초가 소요됩니다. 내가 가지고있는 문제는 그 계획이 몇 시간에 한 번씩 계속해서 재건되고 있다는 것이고 나는 그것이 왜 그렇게 될지 확신하지 못한다.SQL Server 쿼리 실행 계획 다시 작성

이것은 우리가 사용하는 linq 쿼리입니다. 나는 그것이 미친 것처럼 보입니다 만, 우리에게 필요한 것은 이것이 유일한 옵션이라는 것입니다.

var data = from row in mgr.ServiceDesk_RequestEvent 
    .Include("ServiceDesk_Event") 
    .Include("ServiceDesk_Event.ServiceDesk_SLAEventRule") 
    .Include("ServiceDesk_Event.ServiceDesk_SLAEventRule.ServiceDesk_RuleSet") 
    .Include("ServiceDesk_Event.ServiceDesk_SLAEventRule.ServiceDesk_RuleSet.ServiceDesk_Rule") 
    .Include("ServiceDesk_Event.ServiceDesk_SLAEventRule.ServiceDesk_RuleSet.ServiceDesk_Rule.ServiceDesk_RuleOperator") 
    .Include("ServiceDesk_Event.ServiceDesk_SLAEventRule.ServiceDesk_RuleSet.ServiceDesk_Rule.ServiceDesk_RuleConstraintField") 
    .Include("ServiceDesk_Event.ServiceDesk_SLAEventRule.ServiceDesk_RuleSet.ServiceDesk_Rule.ServiceDesk_RuleConstraintValue") 
    .Include("ServiceDesk_Event.ServiceDesk_SLAEventRule.ServiceDesk_RuleSet.ServiceDesk_Action") 
    .Include("ServiceDesk_Request") 
    .Include("ServiceDesk_Request.People_User") 
    .Include("ServiceDesk_Request.ServiceDesk_RequestCategory") 
    .Include("ServiceDesk_Request.ServiceDesk_RequestCategory.ServiceDesk_SLA") 
    .Include("ServiceDesk_Request.ServiceDesk_RequestRole_Groups") 
    .Include("ServiceDesk_Request.ServiceDesk_RequestRole_Groups.Security_Role.Security_UserRoles") 
    .Include("ServiceDesk_Request.ServiceDesk_RequestRole_Groups.Security_Role.Security_UserRoles.Security_User") 
    .Include("ServiceDesk_Request.ServiceDesk_RequestPriority") 
    .Include("ServiceDesk_Request.Offices_User") 
    .Include("ServiceDesk_Request.ServiceDesk_RequestTechnicians") 
    .Include("ServiceDesk_Request.ServiceDesk_RequestTechnicians.People") 
    where row.Completed == false && row.Deleted == false 
    select row; 

여기 생성 된 t-sql은 꽤 크기 때문에 붙여 넣기를 원하지 않습니다. 누구든지 아이디어가 있다면 기꺼이 공헌하십시오.

감사합니다.

+0

네가 맞아. 미쳤어. 당신은 실제로 당신이 포함하는 모든 엔티티의 모든 분야를 필요로합니다. * 그리고 당신은 당신이 프로파일 한 모든 단일 인스턴스 *와 *를 업데이트하려고합니다. 그리고 이것이 개별 수요 로딩보다 빠르다는 것을 알았습니까? 그것이 내가 예상 할 수있는 유일한 합리적인 주장입니다 (읽기 전용 유스 케이스의 첫 번째 선택) 또는 더 작은 쿼리로 분리하는 것입니다. –

답변

1

가능한 원인은 서버의 메모리가 부족하여 쿼리 계획 캐시가 더 빨리 재활용되는 것입니다.

서버의 RAM 용량은 얼마입니까?

질문을 다시 읽으십시오.이 줄은 약간의 걱정입니다. "처음 쿼리를 실행하면 실행 계획이 2 분 이내에 완료됩니다." 간단한 쿼리를 처음 2 분 동안하는 것은 오랜 시간입니다. SQL Server 상자에서 다른 응용 프로그램을 실행합니까?

기본 제공 성능 카운터 인 SQL Server, Plan Cache Counters을 사용하여 모니터링하는 것이 좋습니다. 프로 시저 캐시

실행 계획에서

제거 실행 계획이 프로 시저 캐시에 에게 그 (것)들을 저장하기에 충분한 메모리가 만큼 남아있다. 메모리가 부족하면 데이터베이스 엔진은 비용 기반 접근 방식을 사용하여 캐시에서 프로 시저 캐시에서 제거 할 계획을 결정합니다. 비용 기반 결정을 내리려면 데이터베이스 엔진이 증가하고 은 다음 요소에 따라 각 실행 계획의 현재 비용 변수를 줄입니다. 사용자 프로세스가 캐시 내로 실행 플랜 삽입

상기 사용자 프로세스는 원래의 질의와 동일한 전류 선정 선정 컴파일을 설정; ad-hoc 실행 계획의 경우 사용자 프로세스는 현재 비용을 으로 설정합니다. 그 후 사용자가 프로세스가 실행 계획을 참조 할 때마다 은 현재 비용을 원래 컴파일 비용으로 다시 설정합니다. ad-hoc 실행 계획 사용자 프로세스 은 현재 비용을 증가시킵니다. 계획의 경우 현재 비용의 최대 값은 원래 컴파일 비용입니다.

메모리 부족이 발생하면 데이터베이스 은 캐시에서 실행 계획을 제거하여 응답합니다. 을 제거 할 계획을 결정하기 위해 데이터베이스 엔진은 각 실행 계획의 상태를 검사하고 현재 비용이 0 일 때 계획을 제거합니다.메모리가 압력이 존재하면 현재 비용이 0 인 실행 플랜은 이 자동으로 제거되지 않습니다. 데이터베이스 엔진이 계획을 검사하고 현재 비용이 0 일 때만 이 제거됩니다. 쿼리가 현재 계획을 사용하고 있지 않으면 데이터베이스 엔진이 현재 비용을 현재 비용을 줄임으로써 현재 비용을 0으로 밀어 넣습니다.

은 메모리 요구 사항을 충족하기 위해 이 충분히 제거 될 때까지 실행 계획을 검사합니다. 메모리 의 압력이 존재하는 동안 실행 계획에 의 비용이 한 번 이상 증가하거나 감소 할 수 있습니다 ( ). 메모리 압력 가 더 이상 존재하는 경우, 사용되지 않는 실행 계획의 현재 비용과 모든 실행 계획을 감소 중지 데이터베이스 엔진은 비용이 제로 경우에도 프로 시저 캐시에 남아 없습니다.

데이터베이스 엔진은 모니터 및 사용자 스레드를 사용하여 메모리를 프로 시저 캐시에서 메모리 부담에 대한 응답으로 해제합니다. 리소스 모니터와 사용자 스레드 은 동시 실행 계획을 검사하여 각 사용되지 않은 실행 계획의 현재 비용을 줄입니다. 리소스 모니터는 글로벌 메모리 압력이 존재할 때 프로 시저 캐시에서 실행 계획을 제거합니다. 메모리를 으로 설정하면 시스템 메모리, 프로세스 메모리, 리소스 풀 메모리, 및 모든 캐시의 최대 크기 정책이 적용됩니다.

모든 캐시의 최대 크기는 이고 버퍼 풀 크기는 이며 최대 서버 수는 입니다. 최대 서버 메모리 구성에 대한 자세한 내용은 sp_configure (Transact-SQL)의 최대 서버 메모리 설정을 참조하십시오. 당신이 이미 그것을 본하지 않은 경우

: Plan Caching in SQL Server 2008

+0

서버에 8GB RAM이 있지만 부하가 높지는 않습니다. 그러나 그것이 위대하다는 것을 확인하는 방법이 있다면. – Lukasz

1

This MSDN article는 실행 계획 캐시에 좋은 참조입니다. 실행 계획 사용을 최적화하는 한 가지 방법은 하드 코드 된/동적 SQL 대신 매개 변수화 된 SQL을 사용하는 것입니다.

SELECT * FROM MyTable WHERE [email protected] 

이 같은 계획이 캐시에 상관없이 @Id의 가치가 무엇인지, 재사용 할 수 없습니다으로보다 나은

SELECT * FROM MyTable WHERE ID=1 

입니다. 실행 계획이 재사용 될수록 유용하다고 판단되면 캐시에 남아있을 가능성이 높아집니다.

LINQ가 만드는 문 형식을 알지 못합니다.하지만 염두에 두어야 할 가치가 있습니다. 또한 Mitch가 말했듯이, 메모리가 많을수록 캐시에 저장할 수 있습니다.

또한 여기서는 작동중인 실행 계획 캐싱이 아닙니다.성능에 큰 차이가있는 데이터 캐시도 있습니다. 쿼리를 한 번 실행하면 데이터가 데이터 캐시에 보관되어 후속 호출에서 데이터가 이미 메모리에 저장됩니다. 이는 대부분의 데이터 소스입니다. 성능 차이.

+0

LINQ to Entities는 매개 변수가있는 SQL을 생성하므로 문제는 아닌 것 같습니다. 기사 주셔서 감사합니다! – Lukasz

+0

아 좋아. 최근 데이터 캐시에 대한 최신 편집 내용을 기록해 두십시오. 성능면에서 이점이 있습니다. – AdaTheDev