SQL Server 2008 R2에서 성능 문제가 발생합니다. 쿼리 최적화 프로그램으로 범위를 좁혔습니다. 나는 "왜 이것이 일어나는가, 아니면 버그인가?"라는 결정적인 것을 찾고있다.인덱스를 사용하지 않는 쿼리 최적화
이 예제를 사용 하겠지만 동일한 시나리오의 여러 sprocs에서도 같은 문제가 발생했습니다. 결제 방법이 포함 된 표가 있습니다. 키 필드는 PaymentMethodId 및 UserId입니다. PaymentMethodId는 int이고, PK입니다. UserId는 클러스터되지 않은 인덱스가있는 nvarchar (255)입니다. 가 @id INT = null이 @userId NVARCHAR (255) = NULL 허용하는 SPROC의 시작 부분에 if 문이있다 : 언급 할 가치가
SPROC의 PARAMS :
쿼리는 다음과 유사합니다 두 매개 변수는 모두 널입니다.
select * from PaymentMethods (nolock) pm
where (@userId is null or @userId = pm.UserId)
and (@id is null or @id = pm.PaymentMethodId)
@userId가 널인 경우, 옵티마이 저가 첫 번째 절을 항상 참으로 감지 할 것으로 예상합니다. @userId가 null이 아니면 UserId에 인덱스를 사용할 것으로 기대합니다. @id에 대한 기대치가 같습니다.
우리가 보는 것은 데이터베이스가 전체 테이블 스캔을 수행하기 위해 선택한 입력 값과 상관없이입니다. 이것은 독자적으로 관련되어 있지만 흥미로운 부분입니다.
where 절을 다음과 동등한 것으로 업데이트 할 때 indces를 올바르게 사용하고 있습니다.
select * from PaymentMethods (nolock) pm
where ((@userId is null and pm.UserId is null) OR @userId = pm.UserId)
and (@id is null or @id = pm.PaymentMethodId)
무슨 일입니까? 왜 "@userId가 null입니까?"는 모든 레코드에 대해 고려됩니다 (또는 그럴까요?) 아니면 키보드 앞에 앉아있는 실제 문제입니까?
(a) 테이블이 작거나 (행 수가 적음) 또는 (b) 'SELECT *'를 사용했기 때문에 인덱스가 "표지"할 수있는 방법이 없기 때문일 수 있습니다. 쿼리가 필요하므로 많은 키 검색이 필요하며 궁극적으로 전체 테이블 검색을 수행하는 것보다 비용이 많이 듭니다. –
테이블에 1130 만 레코드가 있고 실제 쿼리는 * 대신 이름으로 필드를 호출합니다. – Jon
쿼리 계획의 스냅 샷을 게시하십시오. 테이블 정의 및 샘플 데이터가 있습니까? 약간의 기록. –