SQL Server : 계획 가이드를 설정할 때의 흐름을 요약했습니다.
그 근처도 근거로, 플랜 가이드를 설정할 때의 순서에 대해 정리해 보았습니다.
참고 : sp_create_plan_guide_from_handle
참고 : sp_control_plan_guide
1. 쿼리의 plan_handle / start_offset 얻기
이번에는 저장 프로 시저의 특정 명령문 실행 계획을 고정화하는 시나리오를 가정합니다.
실행 계획을 고정하는 데 plan_handle이 있으면 유용하므로 sys.dm_exec_query_stats를 사용하여 plan_handle을 검색합니다. 또한 전체 스토어드 플랜을 고정하려면 이것만으로도 괜찮지만 특정 명령문만 고정하려면 start_offset도 가져옵니다.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 100
DB_NAME(qt.dbid) as database_name
,sql_handle
,plan_handle
,qs.statement_start_offset
--query text
,qt.TEXT as parent_query
,SUBSTRING(qt.TEXT, qs.statement_start_offset / 2, (
CASE
WHEN qs.statement_end_offset = - 1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.TEXT)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset
) / 2) as statement
-- average
,total_worker_time / qs.execution_count / 1000 as average_CPU_time_ms
,total_elapsed_time / qs.execution_count / 1000 as average_duration_ms
,total_physical_reads * 8 / qs.execution_count / 1024 as average_physical_reads_mb
-- execution count
,qs.execution_count as execution_count
-- creation / execution time
,last_execution_time
,creation_time
-- total
,total_worker_time / 1000 as total_CPU_time_ms
,total_elapsed_time / 1000 as total_duration_ms
,total_physical_reads * 8 / 1024 as total_physical_reads_mb
-- query plan
,qp.query_plan -- プランもみたいときはコメント外す
FROM sys.dm_exec_query_stats qs
OUTER APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt -- クエリテキスト用
OUTER apply sys.dm_exec_query_plan(plan_handle) as qp -- プランプラン用
WHERE
qt.TEXT like '%ストアドプロシージャ名をここに%'
↑처럼 plan_handle과 start_offset을 얻을 수있었습니다.
아울러, 가이드 고정 후와의 비교용으로 이하의 컬럼의 값도 기록해 둡니다.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 100
DB_NAME(qt.dbid) as database_name
,sql_handle
,plan_handle
,qs.statement_start_offset
--query text
,qt.TEXT as parent_query
,SUBSTRING(qt.TEXT, qs.statement_start_offset / 2, (
CASE
WHEN qs.statement_end_offset = - 1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.TEXT)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset
) / 2) as statement
-- average
,total_worker_time / qs.execution_count / 1000 as average_CPU_time_ms
,total_elapsed_time / qs.execution_count / 1000 as average_duration_ms
,total_physical_reads * 8 / qs.execution_count / 1024 as average_physical_reads_mb
-- execution count
,qs.execution_count as execution_count
-- creation / execution time
,last_execution_time
,creation_time
-- total
,total_worker_time / 1000 as total_CPU_time_ms
,total_elapsed_time / 1000 as total_duration_ms
,total_physical_reads * 8 / 1024 as total_physical_reads_mb
-- query plan
,qp.query_plan -- プランもみたいときはコメント外す
FROM sys.dm_exec_query_stats qs
OUTER APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt -- クエリテキスト用
OUTER apply sys.dm_exec_query_plan(plan_handle) as qp -- プランプラン用
WHERE
qt.TEXT like '%ストアドプロシージャ名をここに%'
2. 고정화
sp_create_plan_guide_from_handle을 사용하여 계획을 고정합니다.
sp_create_plan_guide_from_handle @name = N'プランガイド名'
, @plan_handle = 0x05000000011231231000000001312312312000000
, @statement_start_offset = 1972
3. 확인
여기 를 참고로, 플랜 가이드의 확인 쿼리를 실행합니다.
SELECT plan_guide_id, msgnum, severity, state, message FROM sys.plan_guides OUTER APPLY fn_validate_plan_guide(plan_guide_id);
성공하면 ↓과 같이 메시지가 null인 레코드가 INSERT됩니다. 에러가 되었을 경우는 어떠한 에러 메세지가 message에 출력되고 있으므로 확인이 필요합니다.
SSMS에서도 계획 가이드가 생성되었음을 알 수 있습니다. 속성을 확인하면 더 자세한 정보를 볼 수 있습니다.
``힌트''에 XML이 붙어 있지만, 설정시 지정한 plan_handle의 계획으로 실행하도록, 쿼리 실행시에 힌트구로 XML을 부여해 실행하는 거동과 같습니다.
↓ 플랜 가이드를 스크립팅하면 힌트 절로 부여되었는지 확인할 수 있습니다.
sys.dm_exec_query_stats를 사용하여 캐시된 실행 계획을 다시 확인하면 속성을 볼 때 계획 가이드가 설정되어 있는지 확인할 수 있습니다. 여기까지 확인할 수 있으면, 문제 없이 플랜 가이드가 설정되어, 설정된 플랜으로 실행되고 있다고 안심하고 판단할 수 있습니다.
설정 후에 다시 이하의 3항목을 취득해, 크게 변화하고 있지 않은 것도 확인해 두면 안심입니다.
sp_create_plan_guide_from_handle @name = N'プランガイド名'
, @plan_handle = 0x05000000011231231000000001312312312000000
, @statement_start_offset = 1972
여기 를 참고로, 플랜 가이드의 확인 쿼리를 실행합니다.
SELECT plan_guide_id, msgnum, severity, state, message FROM sys.plan_guides OUTER APPLY fn_validate_plan_guide(plan_guide_id);
성공하면 ↓과 같이 메시지가 null인 레코드가 INSERT됩니다. 에러가 되었을 경우는 어떠한 에러 메세지가 message에 출력되고 있으므로 확인이 필요합니다.
SSMS에서도 계획 가이드가 생성되었음을 알 수 있습니다. 속성을 확인하면 더 자세한 정보를 볼 수 있습니다.
``힌트''에 XML이 붙어 있지만, 설정시 지정한 plan_handle의 계획으로 실행하도록, 쿼리 실행시에 힌트구로 XML을 부여해 실행하는 거동과 같습니다.
↓ 플랜 가이드를 스크립팅하면 힌트 절로 부여되었는지 확인할 수 있습니다.
sys.dm_exec_query_stats를 사용하여 캐시된 실행 계획을 다시 확인하면 속성을 볼 때 계획 가이드가 설정되어 있는지 확인할 수 있습니다. 여기까지 확인할 수 있으면, 문제 없이 플랜 가이드가 설정되어, 설정된 플랜으로 실행되고 있다고 안심하고 판단할 수 있습니다.
설정 후에 다시 이하의 3항목을 취득해, 크게 변화하고 있지 않은 것도 확인해 두면 안심입니다.
4. 돌아가고 싶을 때
플랜 가이드를 설정한 DB를 SSMS로 전개하고 「프로그래밍」→「플랜 가이드」의 아래에 작성되는 플랜 가이드를 삭제하면 OK입니다.
어쨌든 서둘러 무효화하고 싶다면
EXEC sp_control_plan_guide N'DISABLE ALL';
실행하면 괜찮습니다.
5. 주의점
스토어드 프로시저의 일부 또는 모든 플랜을 고정한 경우, 스토어드 프로시저를 ALTER하려면 플랜 가이드를 한 번 제거해야 합니다.
Reference
이 문제에 관하여(SQL Server : 계획 가이드를 설정할 때의 흐름을 요약했습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/maaaaaaaa/items/4b9192719a6263f7c925
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
EXEC sp_control_plan_guide N'DISABLE ALL';
스토어드 프로시저의 일부 또는 모든 플랜을 고정한 경우, 스토어드 프로시저를 ALTER하려면 플랜 가이드를 한 번 제거해야 합니다.
Reference
이 문제에 관하여(SQL Server : 계획 가이드를 설정할 때의 흐름을 요약했습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/maaaaaaaa/items/4b9192719a6263f7c925텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)