簡體   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