SQL Server 쿼리 캐시에서 특정 불량 계획을 제거하려면 어떻게합니까?


33

매우 나쁜 쿼리 계획을 간헐적으로 캐시하는 하나의 특정 SQL Server 2008 쿼리 (저장된 프로시 저는 아니지만 5 분마다 실행되는 동일한 SQL 문자열)가 있습니다.

이 쿼리는 일반적으로 몇 밀리 초 안에 실행되지만이 잘못된 쿼리 계획에서는 30 초 이상이 걸립니다.

프로덕션 데이터베이스 서버에서 전체 쿼리 캐시를 제거하지 않고 SQL Server 2008에서 하나의 잘못된 캐시 된 쿼리 계획 을 외과 적으로 제거하려면 어떻게해야 합니까?


답변:


39

몇 가지를 알아 냈습니다

select * from sys.dm_exec_query_stats

캐시 된 모든 쿼리 계획이 표시됩니다. 불행히도 거기에는 SQL 텍스트가 표시되지 않습니다.

그러나 다음과 같이 SQL 텍스트를 계획에 결합 할 수 있습니다.

select plan_handle, creation_time, last_execution_time, execution_count, qt.text
FROM 
   sys.dm_exec_query_stats qs
   CROSS APPLY sys.dm_exec_sql_text (qs.[sql_handle]) AS qt

여기에서 WHERE내가 아는 SQL을 쿼리에 찾도록 절 을 추가하는 것은 매우 사소한 일입니다.

DBCC FREEPROCCACHE (plan_handle_id_goes_here)

쿼리 계획 캐시에서 각 쿼리 계획을 제거합니다. 아니 정확히 쉽거나 편리하지만, 표시 작업에 ..

편집 : 전체 쿼리 캐시를 덤프 해도 작동하며 적어도 내 경험상 들리는 것보다 덜 위험합니다.

DBCC FREESYSTEMCACHE ('ALL') WITH MARK_IN_USE_FOR_REMOVAL;

2
계획 힌트를 사용하라는 조언은 그다지 중요하지 않습니다.
Remus Rusanu

1
내 쿼리가 마술처럼 새로 고친 후 이것이 잘못된 계획이라는 것을 알았지 만 다음에 테스트 할 계획입니다. 쿼리에 '옵션-염'이있는 경우 계획 힌트가 도움이되지 않습니다. 여기에는 많은 선택적 매개 변수가 있고 한 세트에 대해 최적화 된 후 다른 세트에 대해 실행됩니다. 이런 종류의 쿼리에 첨부 할 수있는 최적의 계획은 없습니다. 한 세트의 매개 변수에 대한 최적의 계획이 있으며, 다른 세트의 매개 변수에 대해서는 끔찍합니다.
Nick.McDermaid 1

6

좋은 계획이 어떻게 생겼는지 아는 경우 계획 힌트를 사용 하십시오 .

특정 캐시 항목을 제거 할 수 없지만을 사용하여 전체 캐시 풀을 정리할 수 있습니다 DBCC FREESYSTEMCACHE(cachename/poolname).

계획 핸들이있는 경우 ( 실행 중 session_id에 대한 sys.dm_exec_requests.plan_handle 에서 또는 실행 후 sys.dm_exec_query_stats 에서) 잘못된 쿼리 계획의 캐시 이름을 얻을 수 있습니다 .

select ce.name
from sys.dm_exec_cached_plans cp
join sys.dm_os_memory_cache_entries ce on cp.memory_object_address = ce.memory_object_address
where cp.plan_handle = @bad_plan

그러나 모든 SQL 계획의 이름은 'SQL 계획'으로 DBCC FREESYSTEMCACHE에 적합한 계획을 선택하는 것이 어려운 선택입니다.

최신 정보

에 대해 잊어 버렸습니다 DBCC FREEPROCCACHE(plan_handle). 그렇습니다.


1
plan_handle을 DBCC FREEPROCCACHE에 전달하는 기능은 SQL Server 2005가 아니라 SQL Server 2008에서 사용할 수 있습니다.
Mario

from에 sys.dm_exec_cached_plans대한 항목이 없으면 무엇을 의미 합니까? plan_handlesys.dm_exec_requests
조나단 길버트

@JonathanGilbert는 계획이 캐시되지 않았거나 캐시에서 제거되었음을 의미합니다. 참조 docs.microsoft.com/en-us/sql/relational-databases/...
레무스 Rusanu

따라서 확인하기 위해 방금 쿼리를 실행하기 시작 했지만 쿼리 에 캐시하지 말 것을 암시하는 힌트가 없다면 SQL Server가 캐시하지 않기로 결정했기 때문에 캐시가 해제 될 수 있습니까? 아직 실행 중이기 때문에 그렇지 않습니까? 계획을 캐시하기로 결정하면 쿼리 실행이 시작 되는 시점부터 캐시 됩니까?
조나단 길버트

1

FREEPROCCACHE의 솔루션은 괜찮지 만,이 일을 더 직접적인 방법은 사용하는 것입니다 OPTION (RECOMPILE)를 가능성이 당신이 생각하기 때문에 (당신이이 SP 아니었다 언급 한) 당신의 SQL 문자열에,이, 엔진을 자사의 단일 사용 계획을 알려줍니다 매개 변수 스니핑이 있거나 통계가 실행마다 크게 다르며 잘못된 캐시 계획 문제가 의심됩니다.

DECLARE @SQL NVARCHAR(4000)
SELECT @SQL = 'SELECT * FROM Table WHERE Column LIKE @NAME OPTION (RECOMPILE)'
EXEC sp_executesql @SQL, N'@NAME varchar(15)', 'MyName' 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.