2011-01-29 5 views
0

두 개의 큰 테이블을 검색하여 값이 있는지 확인하는 기능이 데이터베이스에 있습니다. 매우 큰 쿼리이지만 인덱스를 사용하도록 최적화되어 있으며 일반적으로 매우 빠르게 실행됩니다.SQL 서버 기능의 간헐적 인 성능 문제

지난 2 주 동안 세 번이나이 기능을 사용하기로 결정한 경우,이 기능은 상당히 엉망이되어 결정적으로 느려지므로 성능이 저하되고 성능이 저하 될 수 있습니다. 이는 피크 사용량보다 적은 시간에도 발생합니다.

SQL Server에서 "함수 변경"을 사용하여 함수를 다시 빌드하면 문제가 해결되는 것 같습니다. 일단 그렇게하면 서버 사용량이 정상으로 돌아가고 모든 것이 정상입니다.

이것은 함수 쿼리 계획이 다시 작성되어 올바른 인덱스를 고려한다고 생각하지만 SQL Server가 쿼리 계획을 더 나쁜 계획으로 갑자기 변경하기로 결정한 이유를 알지 못합니다.

아무도이 동작을 일으킬 수있는 아이디어가 있습니까? 아니면 테스트를 거치거나 방지 할 수 있습니까? 우리는 SQL Server 2008 Enterprise를 실행하고 있습니다.

+1

자세한 정보가 필요합니다. 어떤 유형의 함수 (스칼라, 테이블 반환 또는 인라인)입니까? 작동하는 테이블의 구조는 무엇입니까? 어떤 색인이 사용 가능하며 어떤 색인을 사용할 것으로 기대합니까? 나쁘게 행동하기 시작했을 때 정확히 무엇을 했습니까? –

답변

5

설명하는 동작은 잘못 캐시 된 쿼리 계획 및/또는 오래된 통계 때문일 수 있습니다.

그것은 일반적으로 당신이 절의 형식은 그 사람들의, 특히 긴 목록 WHERE A의 매개 변수의 수가 많은 경우에 발생합니다

(@parameter1 is NULL OR TableColumn1 = @parameter1) 

말은, 캐시 된 쿼리 계획이 만료하고, PROC 대표가 아닌 매개 변수 세트로 호출됩니다. 계획은이 데이터 프로파일에 대해 캐시됩니다. 하지만, proc이 매우 다른 매개 변수 집합과 더 자주 사용되는 경우 계획이 적절하지 않을 수 있습니다. 이것은 종종 '매개 변수 스니핑'으로 알려져 있습니다.

이 문제를 완화하고 제거하는 방법이 있지만 트레이드 오프가 포함될 수 있으며 SQL Server 버전에 따라 달라질 수 있습니다. OPTIMIZE FOROPTIMIZE FOR UNKNOWN을 확인하십시오. IF (그리고 큰 경우)는 자주 호출되지 않지만 가능한 한 빨리 실행해야합니다. OPTION(RECOMPILE)으로 표시하여 호출 할 때마다 강제로 다시 컴파일하지만 자주 호출되는 procs 또는 조사는 수행하지 마십시오 .

[참고 : 재 컴파일 및 매개 변수는 논리를 스니핑하는 일부 버전에서 다르게 작동하기 때문에, 당신의 SQL 서버 2008 상자가 가지고있는 Service pack and Cumulative Update (CU) 인식]

실행 (글렌 베리에서)이 쿼리 통계의 상태를 결정하기를 :

-- When were Statistics last updated on all indexes? 
SELECT o.name, i.name AS [Index Name], 
     STATS_DATE(i.[object_id], i.index_id) AS [Statistics Date], 
     s.auto_created, s.no_recompute, s.user_created, st.row_count 
FROM sys.objects AS o WITH (NOLOCK) 
INNER JOIN sys.indexes AS i WITH (NOLOCK) 
ON o.[object_id] = i.[object_id] 
INNER JOIN sys.stats AS s WITH (NOLOCK) 
ON i.[object_id] = s.[object_id] 
AND i.index_id = s.stats_id 
INNER JOIN sys.dm_db_partition_stats AS st WITH (NOLOCK) 
ON o.[object_id] = st.[object_id] 
AND i.[index_id] = st.[index_id] 
WHERE o.[type] = 'U' 
ORDER BY STATS_DATE(i.[object_id], i.index_id) ASC OPTION (RECOMPILE); 
+0

나는 그것이 매개 변수 냄새 맡는 것 같이 들리는 것에 동의한다. 구식 통계는 사실에 맞지 않는 것처럼 보이지만 통계가 좋지 않은 경우'Alter Function'을 통해 계획을 다시 컴파일해도 문제가 해결되지 않습니다. –

+0

통계가 비뚤어지면 (큰 데이터로드 후에) 잘못된 계획이 선택 될 수 있습니다. 그러나 그것은 매개 변수 스니핑으로 인한 것 같습니다. –

관련 문제