ServiceStack花费很长时间来执行存储过程
我已经实现了带有ORMLite连接到我的SQL Server 2014数据库的ServiceStack(v4.0.36)。 我的网站上有一个搜索表单,它将填充的字段作为查询字符串参数传递给“/ search”路由。 我的请求DTO看起来像:
[Route("/search", "GET")]
public class SearchRequest
{
public string FirstName { get; set; }
public string LastName { get; set; }
...
}
(总共有8个参数)然后我有一个服务调用SQL中的存储过程,传递所有参数,如:
public class MyServices : Service
{
public object Get(SearchRequest request)
{
using (var db = AppHostBase.Instance.Container.TryResolve<OrmLiteConnectionFactory>().OpenDbConnection())
{
List<SearchResponse> searchResults = db.SqlList<SearchResponse>("EXEC sp_web_ResultListByNameOrAddress @firstName, @lastName, ...",
new
{
firstName = request.FirstName,
lastName = request.LastName,
...
});
return searchResults;
}
}
}
问题是,如果我通过网站进行搜索,则需要长达30秒的时间才能返回结果(或超时并断开连接)。 如果我在SQL中执行相同的存储过程,我会立即得到结果(搜索字段和组合被索引)。
更改我的web.config后,我注意到一些性能增益
<compilation targetFramework="4.5" debug="false"/>
......但我仍然对发生瓶颈的位置感到困惑。 任何帮助将不胜感激!
呐呐呐呐呐呐呐呐...蝙蝠侠! ?
更新:仅供参考,我通过独立的AngularJS Web应用程序连接到此服务,但在通过邮件服务器等REST客户端测试服务时也会遇到缓慢或超时问题。 谢谢。
更新2:我启用了Mini Profiler ...延迟处于“执行服务”步骤。 以下是一个示例搜索查询:
我打开ORMLite连接上的SQL分析,然后发布任何更新。
更新3:不是超级有用(我认为)... SQL Profiler只显示已执行的存储过程:
更新4:有趣。 因此,我启用了SSMS的SQL Server Profiler与我的请求一起运行,并启用了Mini Profiler,并且还在运行存储过程的线路上的服务实现中设置了一个断点。
当我加载页面时,立即命中断点。 当我继续时,我在SQL Server Profiler中看到“审核登录”消息。 然后在几分钟内没有任何内容,然后使用存储的proc和传递的参数生成“RPC:Completed”消息。
所以这个查询直到最后几乎立即返回(如预期的那样)才会触发SQL。 为什么ServiceStack提交请求和在SQL Server上实际执行的请求之间存在重大延迟? 一切都是本地的,所以我不认为网络问题是罪魁祸首。 任何人?
找到这个链接,它解决了我的问题:调试编译中发生了什么,导致查询执行时间更长?
我有一个bigint数据类型被映射到我的服务响应POCO中的字符串数据类型的存储过程返回。 我在存储过程中添加了一个CONVERT(varchar ...)语句,现在运行速度更快。 谢谢!
重新打开! 对不起,这是如此翻转软盘。 我的单一表单将所有参数提交给存储过程。 我刚刚将ORMLiteConfig超时时间增加到了500秒,并且注意到某些搜索需要大约4分钟才能完成。 同样,在SSMS中执行同样的事情会立即返回结果。 到底是怎么回事??
添加一个额外的答案,因为真的有两个问题。 真正的根似乎与存储过程。 我不知道为什么它不会一直导致问题,但是我使用动态SQL重新构建它以仅包含WHERE过滤器来存在参数。 最初,我有这样的事情:
CREATE [sp_name]
@Name varchar(60) NULL,
@Address varchar(150) NULL
...
AS
BEGIN
SELECT *
FROM tbl_A a
WHERE (@Name IS NULL OR a.Name = @Name)
AND (@Address IS NULL OR a.Address = @Address)
我的想法是,“OR”运算符会先评估上半部分,如果第一个是错误的,则从不尝试评估下半部分。 也许这不是它的工作方式? 无论如何,我最终将其重写为:
CREATE [sp_name]
@Name varchar(60) NULL,
@Address varchar(150) NULL
...
AS
BEGIN
DECLARE @SQL NVARCHAR(4000);
DECLARE @ParamDef NVARCHAR(4000);
SELECT @ParamDef = '
@NameParam varchar(60),
@AddressParam varchar(150),
';
SELECT @SQL = N'
SELECT *
FROM tbl_A a
WHERE 1=1';
IF @Name IS NOT NULL
SELECT @SQL = @SQL + N'
AND a.Name = @NameParam ';
IF @Address IS NOT NULL
SELECT @SQL = @SQL + N'
AND a.Address = @Address ';
EXEC sp_executeSQL
@SQL,
@ParamDef,
@NameParam = @Name,
@AddressParam = @Address;
END
现在工作好多了。 谢谢!
链接地址: http://www.djcxy.com/p/65967.html上一篇: ServiceStack taking a long time to execute stored procedure
下一篇: ServiceStack.Text deserializing an Array with null entries incorrectly