我刚才开始使用dapper.net是出于性能原因而且我真的喜欢命名参数功能而不是在LINQ To sql中运行“ExecuteQuery”.
它适用于大多数查询,但我不时会得到一些非常奇怪的超时.最奇怪的是,只有在通过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事件探查器复制粘贴的查询.我在我的代码中执行它.
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执行的相同查询.
我还可以补充说,这只是(我认为)当我有两个或更多的单词或我在搜索字符串中有一个“停止”字符时发生.所以它可能与全文搜索有关,但我无法弄清楚如何调试它,因为它完美地从Management Studio.
解决方法
Dapper只不过是ado.net上的实用程序包装器;它不会改变ado.net的运作方式.听起来我这里的问题是“在ssms中工作,在ado.net中失败”.这不是唯一的:偶尔发现这种情况很常见.可能的候选人:
>“set”选项:这些选项在ado.net中有不同的默认值 – 并且可能影响性能,尤其是如果你有计算的持久索引列这样的东西 – 如果“set”选项不兼容它可以决定它不能使用存储值,因此不是索引 – 而是表扫描和重新计算.还有其他类似的情况.>系统负载/事务隔离级别/阻塞;在ssms中运行某些东西并不会在那个时刻重现整个系统负载>缓存查询计划:有时一个duff计划被缓存和使用;从ssms运行通常会强制执行一个新计划 – 这自然会根据您在测试中使用的参数进行调整.更新所有索引统计信息等,并考虑添加“optimize for”查询提示