Làm thế nào để có được chi phí cây con ước tính?


7

Nếu tôi có một truy vấn trả về query_plan, ví dụ như thế này:

    SELECT TOP 1000 st.TEXT
    ,cp.size_in_bytes
    ,cp.plan_handle
    ,QP.query_plan
FROM sys.dm_exec_cached_plans AS cp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS QP
WHERE cp.objtype = N'Adhoc'
    AND cp.usecounts = 1

Sau đó, tôi có thể nhấp vào query_plan và di chuột qua biểu tượng hầu hết bên trái, trong đó văn bản mẹo sẽ liệt kê Chi phí Subtree ước tính.

Có cách nào lấy đó Estimated Subtree Costra làm cột riêng cho truy vấn của tôi không?

Tôi hiểu rằng số này không có đơn vị và đề cập đến một PC dành cho nhà phát triển cụ thể khoảng 20 năm trước. Mặc dù vậy, tôi nghĩ rằng nó có thể cho tôi biết thời gian truy vấn sẽ mất bao lâu nếu số liệu thống kê không quá xa.

Tôi đã rất cố gắng với Google để biết thông tin này, nhưng ngay cả dba.stackexchange.com cũng trống rỗng.

Câu trả lời:


7

Tôi tin rằng bạn sẽ phải thực hiện một số công việc truy vấn XML để có được chi phí ước tính đó.

Xem nếu đây là những gì bạn đang tìm kiếm:

   ;WITH XMLNAMESPACES  
    (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan') 
    SELECT TOP 1000 st.text
        ,cp.size_in_bytes
        ,cp.plan_handle
        ,QP.query_plan
        ,n.value('(@StatementSubTreeCost)[1]', 'VARCHAR(128)') AS StatementSubTreeCost
    FROM sys.dm_exec_cached_plans AS cp
    CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st
    CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS QP
    CROSS APPLY query_plan.nodes('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple') AS qn(n)
    WHERE cp.objtype = N'Adhoc'
        AND cp.usecounts = 1
    OPTION(RECOMPILE);

Điều này sẽ trả lại chi phí cho các báo cáo riêng lẻ trong một lô. Bạn có thể cần phải làm việc trong một số nhóm nếu bạn cần tổng chi phí phụ ước tính cho toàn bộ lô.


1

Đây là cách tôi sử dụng câu trả lời cho câu hỏi của tôi.

Tôi là một fan hâm mộ lớn của sp_whoisactive. Nếu bạn không có điều đó, hãy ngừng đọc; tải về tại đây .

Vì vậy, tôi đã thiết lập nó để thu thập ảnh chụp nhanh cứ sau 10 phút, như thế này:

DROP TABLE dbo.HESPOmonitoring_output
DECLARE @s VARCHAR(MAX)
EXEC sp_WhoIsActive 
    @output_column_list = '[login_name][dd%][session_id][program%][sql_com%][sql_text][block%][reads][writes][physical_reads][query_plan][used_memory][tempdb%][wait%][start_time][collection_time][host%][additional%]', @get_outer_command=1, @get_additional_info=1,
    @return_schema = 1, @get_plans=1, 
    @schema = @s OUTPUT
SET @s = REPLACE(@s, '<table_name>', 'dbo.HESPOmonitoring_output')
EXEC(@s)
ALTER TABLE dbo.HESPOmonitoring_output ADD HESPOmonitoring_outputID BIGINT IDENTITY(1,1) NOT NULL
go
SET NOCOUNT ON 
DECLARE @Started DATETIME=DATEADD(DAY, 3, GETDATE())
WHILE 1 > 0 BEGIN 
    EXEC sp_WhoIsActive 
        @output_column_list = '[login_name][dd%][session_id][program%][sql_com%][sql_text][block%][reads][writes][physical_reads][query_plan][used_memory][tempdb%][wait%][start_time][collection_time][host%][additional%]', @get_outer_command=1, @get_additional_info=1,
         @get_plans=1, 
        @destination_table = 'dbo.HESPOmonitoring_output'
    WAITFOR DELAY '00:10:00'
    IF GETDATE() > @Started BREAK  
END 

Tôi đã để nó chạy một lúc (tối đa 3 ngày). Sau đó, tôi chuyển đổi dữ liệu được thu thập như thế này:

/* this query turns HESPOmonitoring_output in a table with one row per SQL statement */
Begin TRY
    DROP TABLE #hespo
END TRY
BEGIN CATCH
END CATCH
;WITH XMLNAMESPACES  
    (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan') 
     SELECT top 10000 H.Start_Time, H.session_id, MAX(H.program_name) AS program_name, MAX(CAST(H.sql_command AS VARCHAR(max))) AS sql_command
    , MAX(CAST(H.sql_text AS VARCHAR(max))) AS sql_text
    , MAX(H.reads) AS reads
    , MAX(H.physical_reads) AS physical_reads
    , MAX(H.writes) AS writes
    , MAX(H.collection_time) AS collection_time
    , MAX(DATEDIFF(second, start_time, collection_time)) AS RunTime
    , MAX(HESPOmonitoring_outputID) AS MaxHESPOmonitoring_outputID
    , MAX(H.blocking_session_id) AS MaxBlocking_session_id
    , Min(H.blocking_session_id) AS MinBlocking_session_id
    , count_big(*) as RowCnt 
    , MAX(TRY_CAST(n.value('(@StatementSubTreeCost)[1]', 'VARCHAR(128)') AS DECIMAL(18,3))) AS StatementSubTreeCost
    INTO #hespo
    FROM dbo.HESPOmonitoring_output H
    CROSS APPLY query_plan.nodes('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple') AS qn(n)
    GROUP BY H.Start_Time, H.session_id

Và cuối cùng tôi nhận được một danh sách hiển thị cho tôi nơi Chi phí ước tính nhỏ so với thời gian chạy, mà không có công việc nào bị chặn cả

SELECT top 10000 
H.StatementSubTreeCost/NULLIF(H.RunTime, 0) AS Ratio, H.StatementSubTreeCost, H.RunTime, *
FROM #hespo H
WHERE H.MinBlocking_session_id IS NULL
AND H.RunTime>0
AND H.StatementSubTreeCost IS NOT NULL
ORDER BY 1 

Đó là một danh sách rất thú vị , nhưng nó đi kèm với một chút tiếng ồn. Để bắt đầu, tôi đã chọn bỏ qua các công việc nhỏ nhanh chóng chỉ chạy dưới 10 phút, nhưng giới hạn đó phụ thuộc vào tình huống của bạn.

Bây giờ việc tìm việc chạy với một kế hoạch tồi tệ sẽ dễ dàng hơn rất nhiều.
Cảm ơn bạn rất nhiều vì đã giúp đỡ của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.