2009-05-05 10 views
3

저는 2 년 조금 넘게 매일 실행되는 쿼리가 있으며 일반적으로 완료하는 데 30 초도 채 걸리지 않았습니다. 갑자기 어제 갑자기 쿼리가 완료 될 때까지 3 시간 이상이 걸리고 전체 시간에 100 % CPU를 사용하고있었습니다.SQL Server 쿼리가 100 % CPU를 사용하고 몇 시간 동안 실행됩니다.

는 SQL은 다음과 같습니다

SELECT 
    @id, 
    alpha.A, alpha.B, alpha.C, 
    beta.X, beta.Y, beta.Z, 
    alpha.P, alpha.Q 
FROM 
    [DifferentDatabase].dbo.fnGetStuff(@id) beta 
    INNER JOIN vwSomeData alpha ON beta.id = alpha.id 

alpha.id은 BIGINT 타입과 beta.id은 INT 유형입니다. dbo.fnGetStuff()WHERE id = @id을 사용하여 동일한 DB의 테이블에 2 개의 INNER JOIN이있는 간단한 SELECT 문입니다. 이 함수는 약 11000 개의 결과를 반환합니다.

보기 vwSomeData은 약 590000 개의 결과를 반환하는 2 개의 INNER JOIN이있는 간단한 SELECT 문입니다.

보기와 기능 모두 자체적으로 실행될 때 10 초 이내에 완료됩니다. 함수의 결과를 임시 테이블로 먼저 선택한 다음 합치면 쿼리가 < 10 초 내에 완료됩니다.

어떻게되는지 어떻게 해결할 수 있습니까? 활동 관리자에 자물쇠가 보이지 않습니다.

답변

0

대형 데이터 집합을 반환하는 함수를 결합 할 때 비슷한 문제가있었습니다. 당신이 이미 제안한 것을해야만했습니다. 결과를 임시 테이블에 넣고 그 테이블에 참여하십시오.

2

SQL Server 프로파일 러 도구를 사용하여 SQL Server에서 실행되는 쿼리를 모니터링 할 수 있습니다. 잠금을 표시하지는 않지만 인덱스를 제안하여 쿼리를 향상시키는 방법에 대한 힌트를 제공 할 수 있습니다.

4

쿼리 계획을 살펴보십시오. 내 생각 엔 실행 계획에 테이블 스캔 이상이 있다는 것입니다. 결과에서 얻을 수있는 몇 가지 기록에 대해 엄청난 양의 I/O가 발생합니다.

1

SQL Server Management Studio의 최신 버전이있는 경우 Tools 아래에 Database Tuning Adviser가 있습니다. 프로파일 러에서 추적을 취하여 때로는 매우 유용한 제안을합니다. 너무 많은 검색어가 없는지 확인하십시오. 조언을 작성하는 데 오랜 시간이 걸립니다.

저는 전문가는 아니지만 과거에는 운이 좋았습니다.

0

추정 된 계획을 살펴보면, 아마도 약간의 빛을 비춰 줄 것입니다. 일반적으로 쿼리 비용이 더 비싸지면 해시 조인이 더 적합한 곳에서 루프 또는 병합 조인이 사용되고 있기 때문에 쿼리 비용이 더 많이 들게됩니다. 예상 된 계획에서 루프 또는 병합 조인을 보는 경우 처리 할 것으로 예상되는 행 수를 살펴보십시오. 실제로 알고있는 행 수보다 훨씬 적습니까? 해시 조인을 사용하는 힌트를 지정하고 더 잘 수행되는지 확인할 수도 있습니다. 그렇다면 통계를 업데이트하고 힌트없이 해시 조인으로 되돌아가는 지 확인하십시오.

SELECT 
    @id, 
    alpha.A, alpha.B, alpha.C, 
    beta.X, beta.Y, beta.Z, 
    alpha.P, alpha.Q 
FROM 
    [DifferentDatabase].dbo.fnGetStuff(@id) beta 
    INNER HASH JOIN vwSomeData alpha ON beta.id = alpha.id 
0

- 장소에 스키마의 유형 아무 생각이없는 그냥 아이디어를 던져하려고 :

다른 사람이 말한 것처럼 ... 프로파일 러를 사용하여 통증의 원인을 찾을 나는 그것이 다른 데이터베이스의 기능이라고 생각하고 있습니다. 그 함수가 고통의 원천이 될 수 있기 때문에, 당신은 [DifferentDatabase]에서 약간의 비정규 화 또는 아무것도 생각하지 않았습니까? 값 비싼 함수보다 인덱스가있는 더 평평한 테이블에 조인 할 때 좀 더 확장 성이 있다는 것을 알게 될 것입니다.

0

실행이 명령을

ON

SET의 SHOWPLAN_ALL는 그런 다음 쿼리를 실행합니다. 실행 계획을 표시하고 인덱스 또는 테이블에서 "SCAN"을 찾습니다. 이제 쿼리에 무슨 일이 일어나고 있는지 가능성이 높습니다. 그렇다면 지금 인덱스를 사용하지 않는 이유를 알아보십시오 (통계 새로 고침 등)

1

함수를 사용해야합니까? @ID를 매개 변수로 전달하는 저장 프로 시저에 전체 내용을 다시 쓸 수 있습니까?

@ID를 변수로 WHERE 절에 전달했기 때문에 테이블에 인덱스가 있어도 쿼리 실행 시간이 크게 늘어날 수 있습니다.

인덱스를 사용할 수없는 이유는 쿼리를 수행하기 위해 액세스 방법을 선택할 때 쿼리 분석기가 변수 값을 알지 못하기 때문입니다. 이 파일은 배치 파일이므로 Transact-SQL 코드가 한 번만 통과하므로 쿼리 최적화 프로그램이 인덱스를 사용하는 액세스 방법을 선택하기 위해 알아야 할 사항을 알지 못하게합니다.

SQL을 다시 쓸 수없는 경우 INDEX 쿼리 힌트를 고려할 수 있습니다.

INDEX가 조각화되어 다시 작성해야 할 수도 있습니다.

+0

테이블 값 기능이 "사용할 수 있기 때문에"사용되는 경우가 너무 많습니다. 더 간단하게 유지하는 것이 좋습니다. 그리고 전망을 분해 해보십시오. SQL Server에서 개체 종속성이 엉망이되면 재미있는 일이 발생합니다. – dkretz

관련 문제