繁体   English   中英

如何减少SQL Server中存储过程的执行时间

[英]How to reduce execution time of stored procedure in SQL Server

我有一个存储过程从列表框中选择数据,微调器输入框和复选框它完美执行但执行大约需要2.30分钟,这导致我的应用程序出错。

错误是

超时已过期。 操作完成之前经过的超时时间或服务器没有响应。

那么如何减少存储过程所需的时间呢?

这是存储过程代码:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[usp_SearchCAMAStructure]
    @section as nvarchar(max),
    @quality as nvarchar(max),
    @style as nvarchar(max),
    @ward as nvarchar(max),
    @improvment as nvarchar(max),
    @condition as nvarchar(max)
AS
BEGIN
    SET NOCOUNT ON;

    Declare @Where as varchar(max)
    Declare @Select as varchar(max)

    Set @Select = ' Distinct vi.struct_no as structure, a.assesmt_no as assessment, o.own_last+'' , ''+o.own_first as taxpayer, id.year_built as built, id.effect_age as age, vi.aprais_val as mktvalue
                From [dbo].assessments a
                inner join parcel p on a.parcel_no = p.parcel_no
                inner join valueimp vi on vi.assesmt_no = a.assesmt_no
                inner join owner o on o.id = a.owner_id
                inner join imp_details id on id.improvementId = vi.id and (id.isdeleted is null or id.isdeleted = 0)
                inner join quality_details qd on qd.quality_id = id.quality_id
                inner join section_details sd on sd.section_id = id.section_id
                inner join style_details stdl on stdl.style_id = id.style_id
                inner join parcel pw on p.ward_no = pw.ward_no'


    Set @Where = ' where  sd.section_id =ISNULL(@section,sd.section_id)
     AND qd.quality_id = ISNULL(@quality,qd.quality_id)
     AND stdl.style_id = ISNULL(@style,stdl.style_id )
     AND pw.ward_no = ISNULL(@ward,pw.ward_no )
     AND id.improvementId = ISNULL(@improvment,id.improvementId )'

    if @condition = 1 --Equal to 
    Begin
        Set @Where = @Where + ' and (' +@improvment+ ' is null or id.effect_age = ' +@improvment+ ' )'
    end
    else 
       if @condition = 2 --Greater than or Equal
       Begin
           Set @Where = @Where + 'and (' +@improvment+ ' is null or id.effect_age > ' +@improvment+ ' )'
       end
       else
          if @condition = 3 --Less than or equal
          Begin
              Set @Where = @Where + 'and (' +@improvment+ ' is null or id.effect_age < ' +@improvment+ ' )'
          end

    DECLARE @QUERY NVARCHAR(MAX)    

    SET @QUERY= 'Select '+ @SELECT + @WHERE 
    print @QUERY

    EXEC sp_executesql @QUERY , N'@section as nvarchar(max) ,@quality as nvarchar(max),@style as nvarchar(max),@ward as nvarchar(max),@improvment as nvarchar(max)',@section ,@quality,@style,@ward,@improvment
END

如果我以下列方式执行存储过程,则需要花费很多时间来执行它

EXEC usp_SearchCAMAStructure null,null,null,null,null,null

那怎么减少呢?

尝试从where子句替换不必要的ISNULL()函数,这也可以提高性能

Set @Where = ' where  ( @section IS NULL OR sd.section_id = @section)
 AND (@quality IS NULL OR qd.quality_id = @quality)
 AND (@style IS NULL OR stdl.style_id = @style)
 AND (@ward IS NULL OR pw.ward_no @ward)
 AND (@improvment IS NULL OR id.improvementId = @improvment)'

您可以尝试使用以下代码更改动态查询。

/****** Object:  StoredProcedure [dbo].[usp_SearchCAMAStructure]    Script Date: 10/18/2016 3:05:14 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[usp_SearchCAMAStructure]
@section as nvarchar(max),
@quality as nvarchar(max),
@style as nvarchar(max),
@ward as nvarchar(max),
@improvment as nvarchar(max),
@condition INT
As
Begin

SET NOCOUNT ON;
SELECT  Distinct vi.struct_no as structure, a.assesmt_no as assessment, o.own_last+'' , ''+o.own_first as taxpayer, id.year_built as built, id.effect_age as age, vi.aprais_val as mktvalue
                From [dbo].assessments a
                inner join parcel p on a.parcel_no = p.parcel_no
                inner join valueimp vi on vi.assesmt_no = a.assesmt_no
                inner join owner o on o.id = a.owner_id
                inner join imp_details id on id.improvementId = vi.id and (id.isdeleted is null or id.isdeleted = 0)
                inner join quality_details qd on qd.quality_id = id.quality_id
                inner join section_details sd on sd.section_id = id.section_id
                inner join style_details stdl on stdl.style_id = id.style_id
                inner join parcel pw on p.ward_no = pw.ward_nowhere  sd.section_id =ISNULL(@section,sd.section_id)
     AND qd.quality_id = ISNULL(@quality,qd.quality_id)
     AND stdl.style_id = ISNULL(@style,stdl.style_id )
     AND pw.ward_no = ISNULL(@ward,pw.ward_no )
     AND id.improvementId = ISNULL(@improvment,id.improvementId) 
     AND  ((@condition=1 AND id.effect_age=@improvment) OR (@condition=2 AND id.effect_age>@improvment) OR (@condition=2 AND id.effect_age<@improvment) OR @condition IS NULL )
END

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM