Проблемы с таймаутом с Dapper.net

dapper database-performance sql

Вопрос

Я начал использовать dapper.net некоторое время назад по соображениям производительности и что мне очень нравится функция названных параметров по сравнению с просто запуском «ExecuteQuery» в LINQ To SQL.

Он отлично работает для большинства запросов, но время от времени я получаю некоторые странные таймауты. Самое странное, что этот тайм-аут происходит только тогда, когда SQL выполняется через dapper. Если я возьму выполненный запрос, скопированный из профилировщика, и просто запустил его в 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();
        }

Я не знаю, с чего начать. Я полагаю, что должно быть что-то, что происходит с dapper, поскольку он отлично работает, когда я просто выполняю код.

Как вы можете видеть на этом снимке экрана. Это тот же запрос, выполняемый с помощью кода, а затем через Management Studio.

введите описание изображения здесь

Я также могу добавить, что это только (я думаю) происходит, когда у меня есть два или более слова или когда у меня есть символ «stop» в строке поиска. Таким образом, у него может быть что-то похожее на полный текстовый поиск, но я не могу понять, как его отлаживать, поскольку он отлично работает с Management Studio.

И чтобы еще хуже, он отлично работает на моем локальном хосте с почти идентичной базой данных как из кода, так и из Management Studio.

Принятый ответ

Dapper - это не что иное, как служебная оболочка над ado.net; он не изменяет работу ado.net. Мне кажется, что проблема здесь «работает в ssms, не удается в ado.net». Это не уникально: довольно часто это бывает редко. Вероятные кандидаты:

  • Опция «установить»: они имеют разные значения по умолчанию в ado.net - и могут влиять на производительность, особенно если у вас есть такие вещи, как расчетные + сохраненные + индексированные столбцы. Если параметры «set» несовместимы, он может решить, что он не может использовать сохраненное значение, следовательно, не индекс - а вместо этого - сканирование таблицы и пересчет. Существуют и другие подобные сценарии.
  • системная загрузка / уровень изоляции транзакции / блокировка; запуск чего-либо в ssms не воспроизводит всю загрузку системы в этот момент времени
  • кэшированные планы запросов: иногда план даффа кэшируется и используется; запуск из ssms обычно приведет к созданию нового плана, который, естественно, будет настроен на параметры, которые вы используете в своем тесте. Обновите всю статистику индекса и т. Д. И подумайте над добавлением подсказки «оптимизировать для»

Популярные ответы

В ADO - значение по умолчанию для CommandTimeout 30 Seconds, в 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 в MSDN



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow