복붙노트

[SQL] 어떻게 SQL Server에서 쿼리 실행 계획을 얻을 수 있습니까?

SQL

어떻게 SQL Server에서 쿼리 실행 계획을 얻을 수 있습니까?

마이크로 소프트 SQL 서버에서 어떻게 쿼리 / 저장 프로 시저에 대한 쿼리 실행 계획을 얻을 수 있나요?

해결법

  1. ==============================

    1.상황에 따라 달라집니다 사용에 하나의 실행 계획을 획득하는 방법에는 여러 가지가 있습니다. 어떤 이유로 SQL Server 관리 Studio에서 쿼리를 실행할 수 있지만 경우에 보통 당신은 당신이 도움이 SQL Server 프로파일 러를 통해 또는 조사하여 계획을 얻을 수 있기를 찾을 수 있습니다, 계획을 얻기 위해 SQL Server Management Studio를 사용할 수 있습니다 계획 캐시.

    상황에 따라 달라집니다 사용에 하나의 실행 계획을 획득하는 방법에는 여러 가지가 있습니다. 어떤 이유로 SQL Server 관리 Studio에서 쿼리를 실행할 수 있지만 경우에 보통 당신은 당신이 도움이 SQL Server 프로파일 러를 통해 또는 조사하여 계획을 얻을 수 있기를 찾을 수 있습니다, 계획을 얻기 위해 SQL Server Management Studio를 사용할 수 있습니다 계획 캐시.

    SQL Server는 단순히 확인합니다 ( "쿼리"메뉴 아래에 있음) "실제 실행 계획 포함"메뉴 항목이 체크되어 있는지 확인하고 정상적으로 조회를 수행하는 매우 쉽게 실행 계획을 캡처 할 수 있도록 깔끔한 기능의 몇 가지와 함께 제공 .

    당신은 당신이 저장 프로 시저를 실행해야 저장 프로 시저의 문에 대한 실행 계획을 얻기 위해 시도하는 경우에, 그래서 좋아한다 :

    exec p_Example 42
    

    쿼리가 완료되면 당신은 별도의 탭 권리 "실행 계획"결과 창에 나타납니다. 당신이 많은 문을 실행 한 경우 당신은이 탭에 표시 많은 계획을 볼 수 있습니다.

    여기에서 SQL Server Management Studio의 실행 계획을 검사 할 수 있습니다, 또는 오른쪽 계획으로 클릭하고 XML 형식의 파일로 계획을 저장하려면 "저장 실행 계획으로 ..."를 선택합니다.

    이 방법은 내가 완성도를 포함 시켰습니다하지만, (이 SQL Server Management Studio를 내부적으로 무엇이다 사실) 방법 1과 매우 유사 또는 SQL Server Management Studio를 사용할 수없는 경우.

    당신이 당신의 쿼리를 실행하기 전에 다음 문 중 하나를 실행합니다. 문은 일괄 처리에서 유일한 문이어야합니다, 즉 같은 시간에 다른 문을 실행할 수 없습니다 :

    SET SHOWPLAN_TEXT ON
    SET SHOWPLAN_ALL ON
    SET SHOWPLAN_XML ON
    SET STATISTICS PROFILE ON
    SET STATISTICS XML ON -- The is the recommended option to use
    

    이러한 연결 옵션입니다 그래서 당신은 단지 연결 당 한 번이를 실행해야합니다. 계획을 볼 때처럼 단순히 쿼리를 실행 - 원하는 형식으로 실행 계획을 포함하는 추가 결과 집합에 의해 acompanied 있습니다됩니다 실행되는 모든 문이 시점에서.

    작업이 완료되면 다음과 같은 문이 옵션을 해제 할 수 있습니다 :

    SET <<option>> OFF
    

    당신은 강한 선호가 없다면 내 추천은 통계 XML 옵션을 사용하는 것입니다. 이 옵션은 "실제 실행 계획 포함"SQL Server 관리 Studio에서 옵션 및 소모품 가장 편리한 형식으로 대부분의 정보에 해당합니다.

    당신이 직접 쿼리를 실행할 수없는 경우 -, 당신은 SQL Server 프로파일 러 추적을 사용하여 계획을 캡처 할 수 있습니다 (또는 귀하의 요청에 당신이 직접 실행할 때 천천히 실행되지 않습니다 우리가 잘못 수행하는 쿼리의 계획이 원하는 기억). 아이디어는 "실행 계획"이벤트 중 하나를 캡처 추적이 실행되는 동안 쿼리를 실행하는 것입니다.

    참고 부하에 따라 프로덕션 환경에이 방법을 사용할 수 있습니다, 그러나 당신은 분명주의해야합니다. 은 SQL Server 프로파일 메커니즘은 데이터베이스에 미치는 영향을 최소화하도록 설계되어 있지만, 이것은 어떤 성능에 영향이 없을 것이라는 점을 의미하지 않는다. 또한 문제 필터링 및 데이터베이스가 많이 사용중인 경우 추적에서 올바른 계획을 확인을 할 수 있습니다. 당신은 분명히 그들은 당신이 자신의 소중한 데이터베이스에이 일에 만족하고 있는지 확인하기 위해 귀하의 DBA 확인해야합니다!

    당신이 얻을 계획은 SQL Server 관리 Studio에서 "실제 실행 계획 포함"옵션과 동일합니다.

    당신이 직접 쿼리를 실행할 수 있으며, 또한 프로파일 러 추적을 캡처 할 수없는 경우에 당신은 여전히 ​​SQL 쿼리 계획 캐시를 검사하여 추정 계획을 얻을 수 있습니다.

    우리는 SQL 서버 DMV에 쿼리하여 계획 캐시를 검사합니다. 다음은 SQL 텍스트와 함께 (XML과 같은) 모든 캐시 된 쿼리 계획을 나열하는 기본 쿼리입니다. 대부분의 데이터베이스에서 당신은 또한에 관심이있는 단지 계획 아래로 결과를 필터링 할 추가 필터링 조항을 추가해야합니다.

    SELECT UseCounts, Cacheobjtype, Objtype, TEXT, query_plan
    FROM sys.dm_exec_cached_plans 
    CROSS APPLY sys.dm_exec_sql_text(plan_handle)
    CROSS APPLY sys.dm_exec_query_plan(plan_handle)
    

    이 쿼리를 실행하고 새 창에서 계획을 열 계획 XML을 클릭 - 마우스 오른쪽 버튼으로 클릭하고 XML 형식의 파일로 계획을 저장 "으로 저장 ... 실행 계획"을 선택합니다.

    당신은 항상 당신이 관심있는 데이터베이스 (성능을 경험하고 일반적으로 하나의 실행 계획을 얻으려고한다 (테이블 및 인덱스 스키마에서 저장된 데이터와 테이블 통계에 이르기까지)과 관련된 많은 요소가 있기 때문에 문제).

    당신은 암호화 된 저장 프로 시저에 대한 실행 계획을 캡처 할 수 없습니다.

    실제 실행 계획은 예상 실행 계획 SQL 서버가 쿼리를 실행하지 않고 어떻게 할 것인지 밖으로 작동하는 반면 SQL 서버가 실제로 쿼리를 실행하는 것입니다. 논리적으로 동일하지만이 쿼리를 실행할 때 실제로 무슨 일이 있었는지에 대한 자세한 정보와 통계를 포함로, 실제 실행 계획은 훨씬 더 유용하다. SQL 서버 추정 (예 : 통계가 최신 인 경우로) 꺼져있는 문제를 진단 할 때이 필수적이다.

    이것은 그 자체 (무료) 책의 주제 가치가 충분하다.

  2. ==============================

    2.포괄적 인 대답 또한 이미 추출 정보를 프로그래밍 방식으로 실행 계획에 액세스 할 수 유용합니다 가끔 기록했다. 이 예제 코드는 다음과 같습니다.

    포괄적 인 대답 또한 이미 추출 정보를 프로그래밍 방식으로 실행 계획에 액세스 할 수 유용합니다 가끔 기록했다. 이 예제 코드는 다음과 같습니다.

    DECLARE @TraceID INT
    EXEC StartCapture @@SPID, @TraceID OUTPUT
    EXEC sp_help 'sys.objects' /*<-- Call your stored proc of interest here.*/
    EXEC StopCapture @TraceID
    
    CREATE PROCEDURE StartCapture
    @Spid INT,
    @TraceID INT OUTPUT
    AS
    DECLARE @maxfilesize BIGINT = 5
    DECLARE @filepath NVARCHAR(200) = N'C:\trace_' + LEFT(NEWID(),36)
    
    EXEC sp_trace_create @TraceID OUTPUT, 0, @filepath, @maxfilesize, NULL 
    
    exec sp_trace_setevent @TraceID, 122, 1, 1
    exec sp_trace_setevent @TraceID, 122, 22, 1
    exec sp_trace_setevent @TraceID, 122, 34, 1
    exec sp_trace_setevent @TraceID, 122, 51, 1
    exec sp_trace_setevent @TraceID, 122, 12, 1
    -- filter for spid
    EXEC sp_trace_setfilter @TraceID, 12, 0, 0, @Spid
    -- start the trace
    EXEC sp_trace_setstatus @TraceID, 1
    
    CREATE  PROCEDURE StopCapture
    @TraceID INT
    AS
    WITH  XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as sql), 
          CTE
         as (SELECT CAST(TextData AS VARCHAR(MAX)) AS TextData,
                    ObjectID,
                    ObjectName,
                    EventSequence,
                    /*costs accumulate up the tree so the MAX should be the root*/
                    MAX(EstimatedTotalSubtreeCost) AS EstimatedTotalSubtreeCost
             FROM   fn_trace_getinfo(@TraceID) fn
                    CROSS APPLY fn_trace_gettable(CAST(value AS NVARCHAR(200)), 1)
                    CROSS APPLY (SELECT CAST(TextData AS XML) AS xPlan) x
                    CROSS APPLY (SELECT T.relop.value('@EstimatedTotalSubtreeCost',
                                                'float') AS EstimatedTotalSubtreeCost
                                 FROM   xPlan.nodes('//sql:RelOp') T(relop)) ca
             WHERE  property = 2
                    AND TextData IS NOT NULL
                    AND ObjectName not in ( 'StopCapture', 'fn_trace_getinfo' )
             GROUP  BY CAST(TextData AS VARCHAR(MAX)),
                       ObjectID,
                       ObjectName,
                       EventSequence)
    SELECT ObjectName,
           SUM(EstimatedTotalSubtreeCost) AS EstimatedTotalSubtreeCost
    FROM   CTE
    GROUP  BY ObjectID,
              ObjectName  
    
    -- Stop the trace
    EXEC sp_trace_setstatus @TraceID, 0
    -- Close and delete the trace
    EXEC sp_trace_setstatus @TraceID, 2
    GO
    
  3. ==============================

    3.

  4. ==============================

    4.이전 답변에 설명 된 방법 옆에, 당신은 또한 무료 실행 계획 뷰어 및 쿼리 최적화 도구 (나는 최근에 충돌 한) ApexSQL 계획을 사용할 수 있습니다.

    이전 답변에 설명 된 방법 옆에, 당신은 또한 무료 실행 계획 뷰어 및 쿼리 최적화 도구 (나는 최근에 충돌 한) ApexSQL 계획을 사용할 수 있습니다.

    설치 및 실행 계획을 직접 SSMS에서 볼 수 있도록, SQL Server Management Studio를로 ApexSQL 계획을 통합 할 수 있습니다.

    ApexSQL 계획에서 예상 실행 계획보기

    ApexSQL 계획에서 실제 실행 계획보기

    쿼리의 실제 실행 계획을 보려면, 2 단계에서 계속 이전에 언급,하지만 예상 계획이 표시되면 지금, ApexSQL 계획의 주요 리본 바에서 "실제"버튼을 클릭합니다.

    은 "실제"버튼을 클릭하면, 실제 실행 계획은 다른 실행 계획 데이터와 함께 비용 매개 변수에 대한 자세한 미리보기로 표시됩니다.

    실행 계획을 보는 방법에 대한 자세한 내용은 다음 링크를 찾을 수 있습니다.

  5. ==============================

    5.획득 깊이 쿼리 실행 계획을 분석하는 나의 마음에 드는 도구는 SQL 센트리 계획 탐색기입니다. 그것은 훨씬 더 사용자 친화적 인 세부 분석 및 SSMS에 비해 실행 계획의 시각화를위한 편리하고 포괄적이다.

    획득 깊이 쿼리 실행 계획을 분석하는 나의 마음에 드는 도구는 SQL 센트리 계획 탐색기입니다. 그것은 훨씬 더 사용자 친화적 인 세부 분석 및 SSMS에 비해 실행 계획의 시각화를위한 편리하고 포괄적이다.

    다음은 기능은 도구에 의해 제공되는 것 아이디어를 가지고 할 수있는 샘플 스크린 샷입니다 :

    이 도구에서 사용할 수있는 뷰의 하나입니다. 당신이 다른 사용자의 실행 계획 표현하고 유용한 추가 정보의 종류도 활용할 수 있습니다 응용 프로그램 창 하단에 탭 세트를 알 수 있습니다.

    또한, 나는 방지 결국 프로 버전을 구입하기 위해 매일 또는 힘을에 그것을 사용하는 자사의 무료 버전의 제한 사항을 발견하지 않았습니다. 그래서, 당신은 그렇게에서 아무것도를 금지를, 무료 버전과 스틱을 선호합니다.

    UPDATE : (마틴 스미스 덕분에) 계획 탐색기는 이제 무료입니다! 자세한 내용은 http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view를 참조하십시오.

  6. ==============================

    6.쿼리 계획은 query_post_execution_showplan 이벤트를 통해 확장 이벤트 세션에서 얻을 수 있습니다. 다음은 샘플 XEvent 세션입니다 :

    쿼리 계획은 query_post_execution_showplan 이벤트를 통해 확장 이벤트 세션에서 얻을 수 있습니다. 다음은 샘플 XEvent 세션입니다 :

    /*
        Generated via "Query Detail Tracking" template.
    */
    CREATE EVENT SESSION [GetExecutionPlan] ON SERVER 
    ADD EVENT sqlserver.query_post_execution_showplan(
        ACTION(package0.event_sequence,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)),
    
    /* Remove any of the following events (or include additional events) as desired. */
    ADD EVENT sqlserver.error_reported(
        ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
        WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
    ADD EVENT sqlserver.module_end(SET collect_statement=(1)
        ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
        WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
    ADD EVENT sqlserver.rpc_completed(
        ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
        WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
    ADD EVENT sqlserver.sp_statement_completed(SET collect_object_name=(1)
        ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
        WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
    ADD EVENT sqlserver.sql_batch_completed(
        ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
        WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
    ADD EVENT sqlserver.sql_statement_completed(
        ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
        WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))) 
    ADD TARGET package0.ring_buffer
    WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
    GO
    

    당신이 (SSMS에서) 세션을 생성 한 후 개체 탐색기로 이동 및 관리에 내려 탐구 | 확장 이벤트 | 세션. 은 "GetExecutionPlan"세션을 마우스 오른쪽 버튼으로 클릭하고 시작합니다. 다시 마우스 오른쪽 버튼으로 클릭하고 "시계 라이브 데이터"를 선택합니다.

    다음으로, 새 쿼리 창을 열고 하나 개 이상의 쿼리를 실행합니다. 여기에서는 AdventureWorks 하나입니다 :

    USE AdventureWorks;
    GO
    
    SELECT p.Name AS ProductName, 
        NonDiscountSales = (OrderQty * UnitPrice),
        Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount)
    FROM Production.Product AS p 
    INNER JOIN Sales.SalesOrderDetail AS sod
        ON p.ProductID = sod.ProductID 
    ORDER BY ProductName DESC;
    GO
    

    탭 : 잠시 두 후에는 "라이브 데이터 GetExecutionPlan"몇 가지 결과를 볼 수 있습니다. 그리드에서 query_post_execution_showplan 이벤트 중 하나를 클릭 한 다음 그리드 아래의 "쿼리 계획"탭을 클릭합니다. 그것은이 유사합니다 :

    편집 : XEvent 코드와 스크린 샷은 SQL / SSMS 2,012w / SP2에서 발생했다. 당신은 SQL 2008 / R2를 사용하는 경우, 당신은 그것을 실행하기 위해 스크립트를 조정할 수 있습니다. 당신이 *이 .sqlplan 파일로 저장, 실행 계획 XML을 추출하고 SSMS에서 엽니 다해야 할 것 그래서하지만이 버전은 GUI가 없습니다. 그것은 성가신입니다. XEvents는 SQL 2005 또는 이전에 존재하지 않았다. 당신은 SQL 2012 이상에하지 않으면 그래서, 난 강력하게 다른 답변 중 하나가 여기에 게시 좋을 것.

  7. ==============================

    7.SQL 서버 2016+에서 시작, 쿼리 저장 기능은 성능을 모니터링하기 위해 도입되었다. 이 쿼리 계획의 선택과 성능에 대한 통찰력을 제공한다. 그것은 추적 또는 확장 이벤트의 전체 교체 아니지만,이 버전으로 버전에서 진화하는 것, 우리는 SQL Server의 향후 릴리스에서 완전한 기능을 쿼리 저장소를 얻을 수 있습니다. 쿼리 스토어의 주요 흐름

    SQL 서버 2016+에서 시작, 쿼리 저장 기능은 성능을 모니터링하기 위해 도입되었다. 이 쿼리 계획의 선택과 성능에 대한 통찰력을 제공한다. 그것은 추적 또는 확장 이벤트의 전체 교체 아니지만,이 버전으로 버전에서 진화하는 것, 우리는 SQL Server의 향후 릴리스에서 완전한 기능을 쿼리 저장소를 얻을 수 있습니다. 쿼리 스토어의 주요 흐름

    참고 : 쿼리 대기 통계 스토어는 SQL 서버에서 사용할 수 2017+

  8. ==============================

    8.여기에 설명 된대로 (이미 설명) SQL Server Management Studio에서와 마찬가지로 Datagrip으로도 가능합니다.

    여기에 설명 된대로 (이미 설명) SQL Server Management Studio에서와 마찬가지로 Datagrip으로도 가능합니다.

  9. ==============================

    9.여기에 모든 전에 말했듯이 외에도 알 수있는 하나의 중요한 점이다.

    여기에 모든 전에 말했듯이 외에도 알 수있는 하나의 중요한 점이다.

    쿼리 계획은 종종 중첩 된 요소의 127 개 레벨의 제한이있는 XML 내장 된 열 유형으로 표현하기에 너무 복잡하다. 그 때문에 일반적으로 대신 사용 sys.dm_exec_text_query_plan에 안전합니다, sys.dm_exec_query_plan는 NULL을 반환 또는 이전 MS SQL 버전에서 오류가 발생 할 수 있습니다 이유 중 하나입니다. 후자 또한 특정 문이 아니라 전체 일괄 처리에 대한 계획을 선택하는 유용한 보너스 기능이 있습니다. 다음은 현재 문을 실행하기위한 계획을 볼 수 사용 방법은 다음과 같습니다

    SELECT p.query_plan
    FROM sys.dm_exec_requests AS r
    OUTER APPLY sys.dm_exec_text_query_plan(
                    r.plan_handle,
                    r.statement_start_offset,
                    r.statement_end_offset) AS p
    

    결과 테이블의 텍스트 열은 XML 컬럼에 비해 그러나 매우 편리하지 않다. 파일에 그 내용을 저장하지 않고, 다이어그램과 같은 별도의 탭으로 열 수 결과를 클릭 할 수 있으려면, 당신은 약간의 트릭을 (단지 XML AS ... CAST을 (사용할 수없는 당신을 기억))를 사용할 수 있습니다 이 있지만, 단 하나의 행에 대해 작동합니다 :

    SELECT Tag = 1, Parent = NULL, [ShowPlanXML!1!!XMLTEXT] = query_plan
    FROM sys.dm_exec_text_query_plan(
                    -- set these variables or copy values
                    -- from the results of the above query
                    @plan_handle,
                    @statement_start_offset,
                    @statement_end_offset)
    FOR XML EXPLICIT
    
  10. ==============================

    10.예상 실행 계획은 SQL 쿼리를 실행하지 않고 최적화에 의해 생성됩니다.

    예상 실행 계획은 SQL 쿼리를 실행하지 않고 최적화에 의해 생성됩니다.

    예상 실행 계획을 취득하기 위하여는, 당신은 쿼리를 실행하기 전에 SHOWPLAN_ALL 설정을 사용하도록 설정해야합니다.

    SET SHOWPLAN_ALL ON

    자, 다음과 같은 SQL 쿼리를 실행할 때 :

    SELECT p.id
    FROM post p
    WHERE EXISTS (
      SELECT 1
      FROM post_comment pc
      WHERE
        pc.post_id = p.id AND
        pc.review = 'Bingo'
    )
    ORDER BY p.title
    OFFSET 20 ROWS
    FETCH NEXT 10 ROWS ONLY
    

    SQL Server는 다음 예상 실행 계획을 생성합니다 :

    | NodeId | Parent | LogicalOp            | EstimateRows | EstimateIO  | EstimateCPU | AvgRowSize | TotalSubtreeCost | EstimateExecutions |
    |--------|--------|----------------------|--------------|-------------|-------------|------------|------------------|--------------------|
    | 1      | 0      | NULL                 | 10           | NULL        | NULL        | NULL       | 0.03374284       | NULL               |
    | 2      | 1      | Top                  | 10           | 0           | 3.00E-06    | 15         | 0.03374284       | 1                  |
    | 4      | 2      | Distinct Sort        | 30           | 0.01126126  | 0.000504114 | 146        | 0.03373984       | 1                  |
    | 5      | 4      | Inner Join           | 46.698       | 0           | 0.00017974  | 146        | 0.02197446       | 1                  |
    | 6      | 5      | Clustered Index Scan | 43           | 0.004606482 | 0.0007543   | 31         | 0.005360782      | 1                  |
    | 7      | 5      | Clustered Index Seek | 1            | 0.003125    | 0.0001581   | 146        | 0.0161733        | 43                 |
    

    우리가 예상 실행 계획을 얻기에 관심이 쿼리를 실행 한 후, 그렇지 않으면, 현재 데이터베이스 세션은 대신 제공하는 SQL 쿼리를 실행 예상 실행 계획을 생성합니다, 같은 SHOWPLAN_ALL을 해제해야합니다.

    SET SHOWPLAN_ALL OFF
    

    은 SQL Server Management Studio의 응용 프로그램에서, 당신은 쉽게 CTRL + L 키 바로 가기를 쳐서 모든 SQL 쿼리의 예상 실행 계획을 얻을 수 있습니다.

    SQL 쿼리를 실행할 때 실제 SQL 실행 계획은 최적화에 의해 생성됩니다. 데이터베이스 테이블 통계가 정확하면, 실제 계획은 추정 하나에서 유의 한 차이가 있습니다.

    SQL 서버의 실제 실행 계획을 얻을, 당신은 STATISTICS IO를 활성화해야합니다하려면, TIME, 프로필 설정, 다음 SQL 명령에 의해 그림과 같이 :

    SET STATISTICS IO, TIME, PROFILE ON
    

    이전 쿼리를 실행할 때 지금, SQL Server는 다음과 같은 실행 계획을 생성하는 것입니다 :

    | Rows | Executes | NodeId | Parent | LogicalOp            | EstimateRows | EstimateIO  | EstimateCPU | AvgRowSize | TotalSubtreeCost |
    |------|----------|--------|--------|----------------------|--------------|-------------|-------------|------------|------------------|
    | 10   | 1        | 1      | 0      | NULL                 | 10           | NULL        | NULL        | NULL       | 0.03338978       |
    | 10   | 1        | 2      | 1      | Top                  | 1.00E+01     | 0           | 3.00E-06    | 15         | 0.03338978       |
    | 30   | 1        | 4      | 2      | Distinct Sort        | 30           | 0.01126126  | 0.000478783 | 146        | 0.03338679       |
    | 41   | 1        | 5      | 4      | Inner Join           | 44.362       | 0           | 0.00017138  | 146        | 0.02164674       |
    | 41   | 1        | 6      | 5      | Clustered Index Scan | 41           | 0.004606482 | 0.0007521   | 31         | 0.005358581      |
    | 41   | 41       | 7      | 5      | Clustered Index Seek | 1            | 0.003125    | 0.0001581   | 146        | 0.0158571        |
    
    SQL Server parse and compile time:
       CPU time = 8 ms, elapsed time = 8 ms.
    
    (10 row(s) affected)
    Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'post'. Scan count 0, logical reads 116, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'post_comment'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    
    (6 row(s) affected)
    
    SQL Server Execution Times:
       CPU time = 0 ms,  elapsed time = 1 ms.
    

    우리가 실제 실행 계획을 얻기에 관심이 쿼리를 실행 한 후,이 같은 설정의 통계 IO, TIME, PROFILE을 해제해야합니다

    SET STATISTICS IO, TIME, PROFILE OFF
    

    은 SQL Server Management Studio의 응용 프로그램에서, 당신은 쉽게 CTRL + M 키 바로 가기를 쳐서 모든 SQL 쿼리의 예상 실행 계획을 얻을 수 있습니다.

  11. ==============================

    11.또한 실제 계획을 얻을 SET STATISTICS XML ON을 사용하여 PowerShell을 통해 할 수 있습니다. 그것은 하나 개의 계획으로 다중 문 계획을 병합 그래서 나는 그것을 서면으로 작성했습니다;

    또한 실제 계획을 얻을 SET STATISTICS XML ON을 사용하여 PowerShell을 통해 할 수 있습니다. 그것은 하나 개의 계획으로 다중 문 계획을 병합 그래서 나는 그것을 서면으로 작성했습니다;

        ########## BEGIN : SCRIPT VARIABLES #####################
        [string]$server = '.\MySQLServer'
        [string]$database = 'MyDatabase'
        [string]$sqlCommand = 'EXEC sp_ExampleSproc'
        [string]$XMLOutputFileName = 'sp_ExampleSproc'
        [string]$XMLOutputPath = 'C:\SQLDumps\ActualPlans\'
        ########## END   : SCRIPT VARIABLES #####################
    
        #Set up connection
        $connectionString = "Persist Security Info=False;Integrated Security=true;Connection Timeout=0;Initial Catalog=$database;Server=$server"
        $connection = new-object system.data.SqlClient.SQLConnection($connectionString)
    
        #Set up commands
        $command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
        $command.CommandTimeout = 0
        $commandXMLActPlanOn = new-object system.data.sqlclient.sqlcommand("SET STATISTICS XML ON",$connection)
        $commandXMLActPlanOff = new-object system.data.sqlclient.sqlcommand("SET STATISTICS XML OFF",$connection)
    
        $connection.Open()
    
        #Enable session XML plan
        $result = $commandXMLActPlanOn.ExecuteNonQuery()
    
        #Execute SP and return resultsets into a dataset
        $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
        $dataset = New-Object System.Data.DataSet
        $adapter.Fill($dataSet) | Out-Null
    
        #Set up output file name and path
        [string]$fileNameDateStamp = get-date -f yyyyMMdd_HHmmss
        [string]$XMLOutputFilePath = "$XMLOutputPath$XMLOutputFileName`_$fileNameDateStamp.sqlplan"
    
        #Pull XML plans out of dataset and merge into one multi-statement plan
        [int]$cntr = 1
        ForEach($table in $dataset.Tables)
        {
                if($table.Columns[0].ColumnName -eq "Microsoft SQL Server 2005 XML Showplan")
                {
    
                    [string]$fullXMLPlan = $Table.rows[0]."Microsoft SQL Server 2005 XML Showplan"
    
                    if($cntr -eq 1)
                        {
    
                        [regex]$rx = "\<ShowPlanXML xmlns\=.{1,}\<Statements\>"
                        [string]$startXMLPlan = $rx.Match($fullXMLPlan).Value
                        [regex]$rx = "\<\/Statements\>.{1,}\<\/ShowPlanXML\>"
                        [string]$endXMLPlan = $rx.Match($fullXMLPlan).Value
    
                        $startXMLPlan | out-file -Append -FilePath $XMLOutputFilePath
    
                        }
    
                    [regex]$rx = "\<StmtSimple.{1,}\<\/StmtSimple\>"
                    [string]$bodyXMLPlan = $rx.Match($fullXMLPlan).Value
    
                    $bodyXMLPlan | out-file -Append -FilePath $XMLOutputFilePath
    
                    $cntr += 1
                } 
        }
    
        $endXMLPlan | out-file -Append -FilePath $XMLOutputFilePath
    
        #Disable session XML plan
        $result = $commandXMLActPlanOff.ExecuteNonQuery()
    
        $connection.Close()
    
  12. ==============================

    12.설명 실행 계획은 매우 상세하고 꽤 독서 시간을 걸리지 만 요약에 당신은 당신이 부분이 먼저 그렇게 실행 된 포함한 많은 정보를 제공해야합니다 쿼리하기 전에 '설명'를 사용하면 할 수 있습니다. 당신이 이것에 대해 좀 더 자세한 내용을 읽어 싶다면, 난 당신 포인트 이것에 대해 작은 블로그뿐만 아니라에 대한 권리 심판을 컴파일. https://medium.com/swlh/jetbrains-datagrip-explain-plan-ac406772c470

    설명 실행 계획은 매우 상세하고 꽤 독서 시간을 걸리지 만 요약에 당신은 당신이 부분이 먼저 그렇게 실행 된 포함한 많은 정보를 제공해야합니다 쿼리하기 전에 '설명'를 사용하면 할 수 있습니다. 당신이 이것에 대해 좀 더 자세한 내용을 읽어 싶다면, 난 당신 포인트 이것에 대해 작은 블로그뿐만 아니라에 대한 권리 심판을 컴파일. https://medium.com/swlh/jetbrains-datagrip-explain-plan-ac406772c470

  13. from https://stackoverflow.com/questions/7359702/how-do-i-obtain-a-query-execution-plan-in-sql-server by cc-by-sa and MIT license