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 ...延迟处于“执行服务”步骤。 以下是一个示例搜索查询:

Mini Profiler屏幕截图

我打开ORMLite连接上的SQL分析,然后发布任何更新。

更新3:不是超级有用(我认为)... SQL Profiler只显示已执行的存储过程:

SQL事件探查器添加了SQL的Mini 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