2015-04-06 69 views
2

我想爲我的標量函數獲取執行計劃,因爲它與僅運行函數體時的執行計劃不同。前段時間我的情況相同,我通過對索引進行碎片整理解決了這個問題(功能並沒有使用碎片索引,因爲碎片很高,但是純粹的查詢卻沒有)。但現在我有< 0.1%的碎片。獲取存儲函數的實際計劃

我可以得到適當的估計執行計劃,但是當我想要得到一個實際的計劃時,我幾乎什麼都得不到。

所以在這裏我只得到無用的外部查詢計劃,但沒有看到在函數中發生了什麼。

它可以修復嗎?


估計的執行計劃:

<ParameterList> 
    <ColumnReference Column="@DateTo" ParameterCompiledValue="NULL" /> 
    <ColumnReference Column="@DateFrom" ParameterCompiledValue="NULL" /> 
    <ColumnReference Column="@ServerID" ParameterCompiledValue="NULL" /> 
    <ColumnReference Column="@ResourceTypeID" ParameterCompiledValue="NULL" /> 
</ParameterList> 

我發現了一個實際的執行計劃功能(由於SQL Server事件探查)

純查詢實際計劃(快): enter image description here 功能(慢): enter image description here

這個功能只是把從表中的一些XML領域,並將它們連接成一個大的XML文件:

ALTER FUNCTION [dbo].[fn_GetErrorXML] 
( 
    @DateFrom datetime,  
    @DateTo datetime,  
    @ResourceTypeID bigint, 
    @ServerID int   
) 
RETURNS NVARCHAR(MAX) 
AS 
BEGIN 

    DECLARE @ErrorDescription VARCHAR(MAX) 
    SET @ErrorDescription = '<root>'; 
    WITH CTE AS 
    ( 

     SELECT 
      d.GeneratedOnUtc, 
      ErrorDescription = cast(d.Data as nvarchar(max)) 
     FROM dbo.AgentData d 
      INNER JOIN dbo.Agent a ON a.CheckID = d.CheckID 
      INNER JOIN dbo.Server s ON a.ServerID = s.ID 
     WHERE d.EventType = 'Result' AND 
       a.ResourceTypeID & @ResourceTypeID > 0 AND 
       s.ID = @ServerID AND 
       d.GeneratedOnUtc between @DateFrom AND @DateTo AND 
       d.Result = 0        
    ) 
    SELECT @ErrorDescription = @ErrorDescription + cte.ErrorDescription 
    FROM CTE  
    ORDER BY cte.GeneratedOnUtc ASC 

    RETURN(@ErrorDescription + '</root>') 
END 
+0

可能參數嗅探。您可能會從緩存中取出計劃並查看它編譯的參數,然後通過將邏輯放入存儲過程並首先使用這些參數值執行它,然後再使用問題中顯示的參數值來重現問題。 – 2015-04-06 10:17:04

+0

您也可以通過探查器或擴展事件檢索實際計劃。這種行爲的原因在這裏討論http://dba.stackexchange.com/a/29749/3690 – 2015-04-06 10:17:58

+0

@MartinSmith請你能詳細解釋一下嗎? – 2015-04-06 10:34:14

回答

0

嗯,回答我最初的問題:你可以使用SQL Server Profiler和配置您的數據庫並獲取了所有的計劃執行查詢,只需在new trace設置中切換chechbox。