2

我正在寻找专家建议来微调示例存储过程(MS SQL 2008R2)以提高性能并遵循最佳实践。

为了解释我的要求,我在下面创建了一个示例程序。

该程序需要执行以下操作

  1. 需要根据参数进行过滤。

  2. 根据@SortExpression例如对数据进行排序。Code Desc或者ImpDate ASC

  3. 返回整个记录集的总记录数。

  4. 返回整个记录集中某个字段的总计。

  5. 最后根据startRowIndex和页面大小仅返回记录集的子集

    CREATE PROCEDURE [dbo].[_getlist](@CompanyID      VARCHAR(10),
                              @IsPaid         VARCHAR(3),
                              @Code           VARCHAR(10) = NULL,
                              @ImpDate        DATETIME = NULL,
                              @BatchNo        INT,
                              @StartRowIndex  INT,
                              @PageSize       INT,
                              @SortExpression VARCHAR(50),
                              @TotalAmount    NUMERIC(15, 2) output,
                              @RecordCount    INT output)
    AS
    BEGIN
       DECLARE @SortDirection VARCHAR(10)
    
       SET @SortDirection = 'ASC'
    
       IF RIGHT(@SortExpression, 5) = ' DESC'
          SET @SortDirection = 'DESC'
    
       DECLARE @SortColumn VARCHAR(50)
    
       SELECT @SortColumn = Replace(@SortExpression, ' ASC', '')
    
       SELECT @SortColumn = Replace(@SortColumn, ' DESC', '')
    
       DECLARE @StartIndex INT,
               @EndIndex   INT
    
       SET @StartIndex = @StartRowIndex
       SET @EndIndex = @StartRowIndex + @PageSize -- (@CurrentPage + 1 )
    
       SELECT data.,
         Row_number()
           OVER (
             ORDER BY CASE WHEN @SortDirection = 'DESC' THEN CASE WHEN
           @SortColumn
           =
           'code' THEN data.client_code END END DESC, CASE WHEN
           @SortDirection
           =
           'ASC'
           THEN CASE WHEN @SortColumn = 'code' THEN data.client_code END END
           ASC )
         AS
         RowNumber
     INTO   #temptable
     FROM   (SELECT *
             FROM   clients
             WHERE  is_local = 'Yes'
                 AND is_paid = 'No'
                 AND status = 'Valid'
                 AND ( company_id = @CompanyID )
                 AND ( ispaid = @IsPaid
                        OR @IsPaid IS NULL )
                 AND ( code = @Code
                        OR @Code IS NULL )
                 AND ( @ImpDate IS NULL
                        OR import_date = @ImpDate )
                 AND ( @BatchNo = 0
                        OR batch_no = @BatchNo )) AS data
    
      SELECT @RecordCount = Count(*)
      FROM   #temptable
    
      SELECT @TotalAmount = Sum(total_tax)
      FROM   #temptable
    
      SELECT *
      FROM   #temptable
      WHERE  rownumber >= @StartIndex
             AND ( rownumber <= @EndIndex OR @PageSize = -1 )
    
      DROP TABLE #temptable
    END  
    

示例只是为了说明要求。我非常感谢任何可以帮助我的帮助。

更新:如前所述,这只是一个用于传达要求的熟化样本。

这是客户端表模式

CREATE TABLE [dbo].[Client](   
    [ID] [int] IDENTITY(1,1) NOT NULL,   
    [CODE] [char](10) NULL,   
    [COMPANY_ID] [char](6) NOT NULL,   
    [CLIENT_ID] [char](6) NOT NULL,   
    [IMP_DATE] [datetime] NOT NULL,   
    [BATCH_NO] [int] NOT NULL,   
    [YTD_Total] [numeric](15, 2) NOT NULL,   
    [STATUS] [char](5) NOT NULL,   
    [MODIFY_DATE] [datetime] NOT NULL,   
    [MODIFY_BY] [varchar](20) NOT NULL,   
    [NOTES] [varchar](100) NULL,   
    [ISPAID] [char](3) NOT NULL,   
    [msrepl_tran_version] [uniqueidentifier] NOT NULL   
)      

谢谢,

4

1 回答 1

1

对于使用 T-SQL 进行分页,我建议查看 SQL Server Common Table Expressions。请参阅此链接中的示例 #2:

http://www.mssqltips.com/sqlservertip/1699/sql-server-stored-procedures-to-page-large-tables-or-queries/

性能指标列在底部——您可以看到它比使用临时表(示例 #1)更快、更高效。

于 2013-10-08T21:23:41.553 回答