sql-server
  • ado.net
  • sql-execution-plan
  • 2011-11-16 45 views 3 likes 
    3

    我一直在閱讀查詢計劃,以及如何最小化由SQL Server爲相同的基本查詢創建的重複計劃。例如,如果我理解正確,使用內聯值發送查詢可能會導致2個不同的查詢計劃。簡單的例子:ADO.NET命令和SQL查詢計劃

    "SELECT FirstName FROM Members WHERE LastName = 'Lee'" 
    "SELECT FirstName FROM Members WHERE LastName = 'MacGhilleseatheanaich'" 
    

    使用存儲過程可以避免這種情況,因爲它可以確保查詢散列值相同。 「姓氏」作爲參數傳遞,例如:現在

    CREATE PROCEDURE sp_myStoredProcedure 
        @LastName varchar(100) 
    AS 
    SELECT FirstName FROM Members WHERE LastName = @LastName 
    Go 
    

    ,我的問題是,是否同樣適用於Command對象(如SQLClient.SQLCommand在ADO.NET)。我問的原因是字符串參數沒有定義的最大長度,如上面的代碼。看看下面的代碼:

    MyCmd.CommandText = "SELECT FirstName FROM Members WHERE LastName = @LastName" 
    MyCmd.Parameters.AddWithValue("@LastName", "Lee") 
    

    再後來:

    MyCmd.Parameters.Clear() 
    MyCmd.Parameters.AddWithValue("@LastName", "MacGhilleseatheanaich") 
    

    由於@LastName尚未宣佈SQL Server作爲具有限定的最大長度,將SQL Server中創建的每一個新的查詢計劃這種方式執行命令時有不同的值嗎?

    我的問題主要來自於閱讀.NET 3.5中的LINQ2SQL如何通過定義不同的參數長度來錯過緩存(http://damieng.com/blog/2009/12/13/sql-server-query-plan-cache)。由於長度在使用Command對象時沒有定義,它是否會共享相同的問題?

    回答

    3

    你paramaterized查詢實際發送到服務器存儲過程sp_executesql的系統調用,這是非常擅長試圖在可能通過的無人居住聲明面具的哈希值與那些比較重用查詢計劃計劃仍然存在於緩存中,所以如果可能的話,並且服務器認爲它是合適的,那麼計劃重用(以及可能的參數嗅探問題)的可能性很大。

    還值得一提的是,Simple Parameterization幾乎可以保證你的第一個例子中的兩個語句實際上最終會使用相同的計劃。

    +0

    感謝,也許我應該補充另外一個我想問的原因是通過閱讀.NET 3.5中的LINQ2SQL如何通過定義不同的參數長度來錯過緩存(http://damieng.com/blog/2009/12/13/sql -server查詢計劃緩存)。由於長度在使用Command對象時沒有定義,它是否會共享相同的問題? –

    +0

    對於簡單參數化來說,參數長度並不重要,因爲總是假定這種類型的最大尺寸,我認爲這是sqlcommand params的情況,但顯然它不是; http://msdn.microsoft.com/en-us/magazine/ee236412.aspx#id0070056所以你對不同計劃的假設是正確的,我的答案只適用於固定大小類型或可變大小類型,其中相同大小一致指定。 –

    0

    可以將查詢提示添加到您的SP中,以控制何時創建QEP。這可能無法解決您的特定問題(或者確實回答您的具體問題!),但網絡上的許多信息都是關於此問題的。 http://msdn.microsoft.com/en-us/library/ms190727.aspx

    相關問題