2013-03-28 40 views
8

前段時間我出於性能方面的考慮開始使用dapper.net,並且我真的很喜歡命名參數功能,而不是在LINQ To SQL中運行「ExecuteQuery」。Dapper.net奇怪的超時問題

它適用於大多數查詢,但我時常會遇到一些非常奇怪的超時問題。最奇怪的是,這個超時只發生在通過dapper執行SQL時。如果我從分析器中複製執行的查詢並在Management Studio中快速運行它,並且工作完美。這不僅僅是一個暫時的問題。查詢始終通過dapper超時,並在Management Studio中始終正常工作。

exec sp_executesql N'SELECT Item.Name,dbo.PlatformTextAndUrlName(Item.ItemId) As PlatformString,dbo.MetaString(Item.ItemId) As MetaTagString, Item.StartPageRank,Item.ItemRecentViewCount 
        NAME_SRCH.RANK as NameRank, 
        DESC_SRCH.RANK As DescRank, 
        ALIAS_SRCH.RANK as AliasRank, 
        Item.itemrecentviewcount, 
        (COALESCE(ALIAS_SRCH.RANK, 0)) + (COALESCE(NAME_SRCH.RANK, 0)) + (COALESCE(DESC_SRCH.RANK, 0)/20) + Item.itemrecentviewcount/4 + ((CASE WHEN altrank > 60 THEN 60 ELSE altrank END) * 4) As SuperRank 
        FROM dbo.Item 
        INNER JOIN dbo.License on Item.LicenseId = License.LicenseId 

        LEFT JOIN dbo.Icon on Item.ItemId = Icon.ItemId 
        LEFT OUTER JOIN FREETEXTTABLE(dbo.Item, name, @SearchString) NAME_SRCH ON 
        Item.ItemId = NAME_SRCH.[KEY] 
        LEFT OUTER JOIN FREETEXTTABLE(dbo.Item, namealiases, @SearchString) ALIAS_SRCH ON 
        Item.ItemId = ALIAS_SRCH.[KEY] 
        INNER JOIN FREETEXTTABLE(dbo.Item, *, @SearchString) DESC_SRCH ON 
        Item.ItemId = DESC_SRCH.[KEY] 
        ORDER BY SuperRank DESC OFFSET @Skip ROWS FETCH NEXT @Count ROWS ONLY',N'@Count int,@SearchString nvarchar(4000),@Skip int',@Count=12,@SearchString=N'box,com',@Skip=0 

這就是我從SQL Profiler粘貼的查詢。我在我的代碼中像這樣執行它。

  using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Conn"].ToString())) { 
      connection.Open(); 
      var items = connection.Query<MainItemForList>(query, new { SearchString = searchString, PlatformId = platformId, _LicenseFilter = licenseFilter, Skip = skip, Count = count }, buffered: false); 
      return items.ToList(); 
     } 

我不知道從哪裏開始。我想應該有一些事情正在發生,因爲它只是在執行代碼時工作正常。

正如你在這個截圖中看到的。這是通過代碼先執行然後通過Management Studio執行的相同查詢。

enter image description here

我還可以補充一點,這只是(我認爲)發生時,我有兩個或兩個以上的詞或當我在搜索字符串「停止」字符。因此,它可能有全文搜索的東西,但我不知道如何調試它,因爲它可以完美地從Management Studio中運行。

而且更糟糕的是,它在我的本地主機上運行正常,代碼和Management Studio的數據庫幾乎完全相同。

回答

7

Dapper只不過是ado.net上的實用程序封裝;它不會改變ado.net的運作方式。聽起來這裏的問題是「在ssms中工作,在ado.net中失敗」。這並不是獨一無二的:偶爾會發現這種情況很常見。可能的候選人:

  • 「設置」選項:這些都在ado.net不同的默認值 - 特別是如果你有事情等來計算+堅持+索引的列會影響性能 - 如果「設置」選項不兼容它可以決定它不能使用存儲的值,因此不能使用索引 - 而是使用表掃描和重新計算。還有其他類似的情況。
  • 系統加載/事務隔離級別/阻塞;在ssms中運行某些內容不會在當時及時重現整個系統負載
  • 緩存的查詢計劃:有時會緩存並使用duff計劃;從ssms運行通常會強制執行一個新計劃 - 自然會針對您在測試中使用的參數進行調整。更新所有索引統計等,並考慮添加「優化」查詢提示
+0

不好意思見我已故的答覆,但它是一種很難測試。無論如何,我認爲它必須處理緩存的查詢計劃。我現在在本地得到了時間,並重新啓動了服務器,然後運行。我現在嘗試添加一個「優化」的東西。希望這會有所幫助。感謝您的見解! – Olaj

6

在ADO中是CommandTimeout 30秒的默認值,在Management Studio無窮大中。調整查詢<>的命令超時時間,請參閱下文。

var param = new { SearchString = searchString, PlatformId = platformId, _LicenseFilter = licenseFilter, Skip = skip, Count = count }; 
var queryTimeoutInSeconds = 120; 
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Conn"].ToString())) 
{ 
    connection.Open(); 
    var items = connection.Query<MainItemForList>(query, param, commandTimeout: queryTimeoutInSeconds, buffered: false); 
    return items.ToList(); 
} 

SqlCommand.CommandTimeout Property on MSDN