2013-03-28 10 views
8

Zacząłem używać dapper.net jakiś czas temu ze względów wydajnościowych i naprawdę podoba mi się funkcja nazwanych parametrów w porównaniu do uruchomienia "ExecuteQuery" w LINQ To SQL.Dziwne problemy z przekroczeniem limitu czasu z Dapper.net

Działa doskonale w przypadku większości zapytań, ale od czasu do czasu dostaję naprawdę dziwne błędy. Najdziwniejsze jest to, że ten limit czasu występuje tylko wtedy, gdy SQL jest wykonywany przez dapper. Jeśli wziąłem wykonaną kwerendę skopiowaną z profilera i po prostu uruchomiłem ją w Management Studio szybko i działa idealnie. I to nie tylko chwilowe problemy. Kwerenda konsekwentnie limitu czasu przez lepsze i konsekwentnie działa dobrze w 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 

To jest zapytanie skopiowane do skopiowania z programu SQL Profiler. Wykonuję to w ten sposób w moim kodzie.

  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(); 
     } 

Nie mam pojęcia, od czego zacząć. Przypuszczam, że musi być coś, co dzieje się z eleganckim, ponieważ działa dobrze, gdy po prostu wykonuję kod.

Jak widać na tym zrzucie ekranu. To jest to samo zapytanie wykonywane najpierw przez kod, a następnie przez Management Studio.

enter image description here

Mogę również dodać, że to tylko (chyba) się dzieje, gdy mam dwie lub więcej słów lub gdy mam char „stop” w ciągu wyszukiwania. Więc może mieć coś do zrobienia z pełnym przeszukiwaniem tekstu, ale nie mogę znaleźć sposobu na jego debugowanie, ponieważ działa doskonale z Management Studio.

Co gorsza, działa dobrze na moim lokalnym serwerze z niemal identyczną bazą danych zarówno z kodu, jak iz Management Studio.

Odpowiedz

7

Dapper to nic więcej niż opakowanie narzędzia na ado.net; nie zmienia to działania ado.net. Wydaje mi się, że problemem jest "działa w ssms, kończy się niepowodzeniem w ado.net". Nie jest to wyjątkowy przypadek: dość często zdarza się, że tak się dzieje. Prawdopodobnymi kandydatami:

  • „set” opcję: te mają różne wartości domyślne w ADO.NET - i może wpłynąć na wydajność zwłaszcza jeśli mają takie rzeczy jak obliczono + utrzymywała + indeksowanych kolumn - jeśli „set” opcje nie są kompatybilne może zdecydować, że nie może użyć zapisanej wartości, a więc nie indeksu - a zamiast tego skanować tabelę i przeliczać. Istnieją inne podobne scenariusze.
  • system/poziom izolacji/blokowanie systemu; uruchomienie czegoś w ssms nie odtwarza całego obciążenia systemu w danym momencie w czasie
  • plany zapytań buforowanych: czasami plan duff zostaje zbuforowany i użyty; uruchamianie z SSms zazwyczaj wymusza nowy plan - który oczywiście zostanie dostrojony pod kątem parametrów, których używasz w teście. Zaktualizować wszystkie swoje statystyki indeksów itp, i rozważyć dodanie „optymalizacji” nutą zapytań
+0

przepraszam za moje opóźnienie w odpowiedzi, ale to było trochę trudne do badania. W każdym razie myślę, że miało to związek z planami zapytań z pamięci podręcznej. Dostałem teraz czas lokalnie i zrestartowałem serwer, a następnie zadziałało. Próbowałem teraz dodać "OPTYMALIZACJĘ". Mam nadzieję, że to pomoże. Dzięki za spostrzeżenia! – Olaj

6

W ADO jest wartością domyślną dla CommandTimeout 30 sekund w Management Studio nieskończoność. Dostosuj limit czasu polecenia, aby wywołać zapytanie <>, patrz poniżej.

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(); 
} 

Zobacz także SqlCommand.CommandTimeout Property on MSDN

Powiązane problemy