2016-06-17 145 views
1

將此作爲一個更廣泛的問題發佈,但請讓我知道實際查詢是否有助於解決此問題。選項(重新編譯)加快查詢執行速度

我們有一個查詢需要約30秒的時間來執行,由於執行計劃的判斷有多種原因。查詢由實體框架生成,當然有一些低效率,所以這不是重點。

當我們DBCC FREEPROCCACHE並提交查詢時,原來〜30秒的運行時間。當使用OPTION(RECOMPILE)暗示查詢時,它是即時的(並且計劃更加合理)。

如果查詢在第一個場景中第一次遇到服務器,爲什麼結果會不一致,因此應該第一次編譯計劃?

旁註: - 4136等

  • 跟蹤標誌在去之前

    更新 - 增加計劃:

  • +1

    這是一個參數嗅探問題的腳印之一。 – RBarryYoung

    +0

    可能受益於[參數嵌入優化](http://sqlperformance.com/2013/08/t-sql-queries/parameter-sniffing-embedding-and-the-recompile-options)沒有查詢和計劃誰知道? –

    +0

    如果您將「好」計劃與重新編譯和「壞」計劃進行比較,您應該弄清楚有什麼不同。用於編譯它的參數位於最左邊的節點中。 –

    回答

    0

    這看起來並不像參數嗅探。

    的CompiledValue和RunTimeValue是所有參數不變,即使在bad.sqlplan

    <ParameterList> 
        <ColumnReference Column="@p__linq__16" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" /> 
        <ColumnReference Column="@p__linq__15" ParameterCompiledValue="N'ABCD4'" ParameterRuntimeValue="N'ABCD4'" /> 
        <ColumnReference Column="@p__linq__14" ParameterCompiledValue="(10776)" ParameterRuntimeValue="(10776)" /> 
        <ColumnReference Column="@p__linq__13" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" /> 
        <ColumnReference Column="@p__linq__12" ParameterCompiledValue="(0)" ParameterRuntimeValue="(0)" /> 
        <ColumnReference Column="@p__linq__11" ParameterCompiledValue="N'ABCD4'" ParameterRuntimeValue="N'ABCD4'" /> 
        <ColumnReference Column="@p__linq__10" ParameterCompiledValue="N'ABCD4'" ParameterRuntimeValue="N'ABCD4'" /> 
        <ColumnReference Column="@p__linq__9" ParameterCompiledValue="NULL" ParameterRuntimeValue="NULL" /> 
        <ColumnReference Column="@p__linq__8" ParameterCompiledValue="NULL" ParameterRuntimeValue="NULL" /> 
        <ColumnReference Column="@p__linq__7" ParameterCompiledValue="NULL" ParameterRuntimeValue="NULL" /> 
        <ColumnReference Column="@p__linq__6" ParameterCompiledValue="N'ABCD4'" ParameterRuntimeValue="N'ABCD4'" /> 
        <ColumnReference Column="@p__linq__5" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" /> 
        <ColumnReference Column="@p__linq__4" ParameterCompiledValue="(513)" ParameterRuntimeValue="(513)" /> 
        <ColumnReference Column="@p__linq__3" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" /> 
        <ColumnReference Column="@p__linq__2" ParameterCompiledValue="(513)" ParameterRuntimeValue="(513)" /> 
        <ColumnReference Column="@p__linq__1" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" /> 
        <ColumnReference Column="@p__linq__0" ParameterCompiledValue="(513)" ParameterRuntimeValue="(513)" /> 
    </ParameterList> 
    

    相反,它看起來好像你是從The Parameter Embedding Optimization受益。

    查詢文本在計劃中被截斷,但我可以看到您正在比較參數與文字的位置。也許這是一個catch all query

    enter image description here

    當您使用OPTION (RECOMPILE)計劃編制具有用於傳遞的參數值工作。 SQL Server可以查看傳遞參數的值,並用TRUEFALSE有效替換突出顯示的表達式。

    這可能允許它簡化計劃的整個分支,如果它們與傳遞的參數值無關。

    這方面的一個簡單的例子是

    EXEC sys.sp_executesql 
        N'SELECT * FROM master..spt_values WHERE @Param <> 0 OPTION (RECOMPILE)', 
        N'@Param INT', 
        @Param = 0; 
    

    該計劃被編譯時@Param=0和它僅需要對這個值所以@Param <> 0可以在編譯時被評價爲false和計劃是正確的根本不訪問表格。

    enter image description here

    沒有OPTION (RECOMPILE)你看這

    EXEC sys.sp_executesql 
        N'SELECT * FROM master..spt_values WHERE @Param <> 0', 
        N'@Param INT', 
        @Param = 0; 
    

    enter image description here

    即使嗅探到的參數值和運行參數值是相同的計劃不能被優化到相同的程度因爲它將被緩存,並且如果傳遞了不同的參數值,仍然需要工作。