내 사무실에는 꽤 추한 쿼리가 있지만 프로덕션 및 개발 환경 (각각 20 초 및 4 초)에서 잘 실행됩니다. 그러나 테스트 환경에서는 4 시간 이상이 소요됩니다. SQL2005 (+ 최신 패치)가 프로덕션 및 개발에서 실행 중입니다. SQL2008R2가 테스트 중입니다.
쿼리 계획을 살펴본 결과 SQL2008R2가 연결된 서버에서 반환 된 행을 저장하기 위해 테이블 스풀 (lazy spool)을 통해 TempDB를 사용하고 있음을 보여줍니다. 다음 단계는 쿼리의 96.3 %를 차지하는 중첩 루프 (왼쪽 반 세미 조인)를 표시하는 것입니다. 두 사업자 사이의 노선은 5,398MB입니다!
SQL 2005에 대한 쿼리 계획은 tempdb를 사용하지 않고 Left Anti Semi Join을 사용하지 않음을 보여줍니다.
아래는 위생 처리 된 코드이며 실행 계획은 2005 년 계획을 맨 위에, 2008R2는 맨 아래를 계획합니다.
급격한 속도 저하 및 변화의 원인은 무엇입니까? 다른 실행 계획을 기대하고 있었기 때문에 귀찮게하지 않습니다. 쿼리 시간이 크게 느려지면 문제가 발생합니다.
2008R2 버전이 tempdb를 사용하고 있기 때문에 기본 하드웨어를 살펴 봐야합니까, 사용법을 최적화하는 방법을 살펴 봐야합니까?
쿼리를 작성하는 더 좋은 방법이 있습니까?
도와 주셔서 감사합니다.
INSERT INTO Table1_GroupLock (iGroupID, dLockedDate)
SELECT
Table1.iGroupID,
GETDATE()
FROM Table1
WHERE
NOT EXISTS (
SELECT 1
FROM LinkedServer.Database.Table2 Alias2
WHERE
(
Alias2.FirstName + Alias2.LastName = dbo.fnRemoveNonLetter(Table1.FullName)
AND NOT dbo.fnRemoveNonLetter(Table1.FullName) IS NULL
AND NOT Alias2.FirstName IS NULL
AND NOT Alias2.LastName IS NULL
) OR (
Alias2.FamilyName = dbo.fnRemoveNonLetter(Table1.FamilyName)
AND Alias2.Child1Name = dbo.fnRemoveNonLetter(Table1.Child1Name)
AND NOT dbo.fnRemoveNonLetter(Table1.FamilyName) IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.Child1Name) IS NULL
AND NOT Alias2.Familyname IS NULL
AND NOT Alias2.Child1Name IS NULL
) OR (
Alias2.StepFamilyName = dbo.fnRemoveNonLetter(Table1.StepFamilyName)
AND Alias2.StepFamilyNameChild1 = dbo.fnRemoveNonLetter(Table1.StepFamilyNameChild2)
AND NOT Alias2.StepFamilyName IS NULL
AND NOT Alias2.StepFamilyNameChild1 IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.StepFamilyName) IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.StepFamilyNameChild2) IS NULL
)
) AND NOT EXISTS (
SELECT 1
FROM Table3
INNER JOIN Table4
ON Table4.FirstNameType = Table3.FirstNameType
INNER JOIN table5
ON table5.LastNameType = Table3.LastNameType
WHERE
Table3.iGroupID = Table1.iGroupID
AND Table3.bIsClosed = 0
AND Table4.sNameTypeConstant = 'new_lastname'
AND table5.sFirstNameConstant = 'new_firstname'
)
:: EDIT :: 다른 SQL2005 인스턴스에서 쿼리를 실행했습니다. "좋은 인스턴스"와 거의 동일한 실행 계획입니다. 2008R2 인스턴스보다 2008R2 인스턴스보다 두 2005 버전이 2008R2 연결된 서버에서 어떻게 더 잘 실행되는지 확실하지 않습니다.
코드가 일부 작업을 사용할 수 있다는 것을 부인하지는 않지만 코드가 문제라면 모든 시험에서 동일한 실행 계획이 보이지 않습니까? SQL 버전에 관계없이?
:: 편집 :: SP1과 CU3을 2008R2 인스턴스 모두에 적용했지만 주사위는 없습니다. 연결된 서버에서 배열을 구체적으로 설정했습니다. 주사위는 없습니다. 두 인스턴스 모두에서 사용자 계정의 권한을 sysadmin으로 설정했습니다. 또한 SQL Server 2008 내부 및 문제 해결을 기억했으며, 어떻게 추적 할 수 있는지 확인할 것입니다.
도움과 팁을 주셔서 감사합니다.
:: 편집 :: 연결된 서버에 대한 다양한 권한 변경을 수행했습니다. SQL 로그인, 도메인 로그인, 사용자를 가장하고 "이 보안 컨텍스트를 사용하여 작성"옵션을 사용했습니다. 서버에서 sysadmin 권한을 가진 연결된 서버의 양쪽에 사용자를 만들었습니다. 아이디어가 없습니다.
SQL2005가 SQL2008R2와 크게 다른 쿼리를 실행하는 이유를 여전히 알고 싶습니다. 잘못된 쿼리 인 경우 SQL2005와 SQL2008R2 모두에서 4 시간 이상의 런타임이 표시됩니다.