【问题标题】:SQL Server Dynamic Order By Performance IssueSQL Server 按性能问题动态排序
【发布时间】:2016-03-02 05:27:50
【问题描述】:

1.这是检索记录的过程(最大的表大约有 1M 行)

Create Procedure GetallTransctions(@Pagesize,@CurrentPage,@SortColumn,@SortDirection)
AS
Begin

select TOP (@PageSize) * from (

  Select Top ((@PageSize*CurrentPage)+@PageSize) * from TransactionDetails where 
  TransactionType ='Pay'--Few more conditions
  Order By 
  case when @SortColumn= 'CustomerName' and @SortDirection= 'ASC' 
  then CustomerName end asc, 
  case when @SortColumn= 'CustomerName' and @SortDirection= 'DESC' 
  then CustomerName end desc

  ) a

在行数小于 1M 之前,上述过程性能良好。当记录大小不断增加时,执行大约需要 40 秒。如果我像这样对订单进行硬编码

Order By 
  CustomerName ASC

查询需要 3-5 秒才能执行,但我无法对排序列进行硬编码。 Case 语句 in order by 子句会影响性能吗?任何解决方案/查询。

2.以上过程实现了分页。因此,假设我需要选择 70000 - 70010 范围内的记录。我们根据参数值应用排序,获取 0-70010 并获取前 10 条记录。而是应用排序并仅获取 70000 - 70010。还有其他方法吗?

【问题讨论】:

    标签: sql-server dynamic sql-order-by case-statement sqlperformance


    【解决方案1】:

    问题可能是 SQL 优化器无法识别索引可用于排序。

    解决办法是使用动态SQL。

    declare @sql nvarchar(max);
    
    set @sql = '
    select TOP (@PageSize) * from (
      Select Top ((@PageSize*CurrentPage)+@PageSize) * from TransactionDetails where 
      TransactionType =''Pay'' --Few more conditions
    ';
    
    if @SortColumn = 'CustomerName' and @SortDirection = 'ASC' 
      set @sql = @sql + ' order by CustomerName asc';
    else if  @SortColumn = 'CustomerName' and @SortDirection = 'DESC' 
      set @sql = @sql + ' order by CustomerName desc';
    
    set @sql = replace(@sql, '@Pagesize', @Pagesize);
    
    exec sp_executesql @sql;
    

    这将在每次运行时重新编译查询(产生开销)。但是,如果排序可以使用索引,它也应该可以快速获取您要查找的数据。

    此外,在 SQL Server 2012+ 中,您可以使用 offset/fetch 子句,这对于分页来说更好。

    【讨论】:

    • 最初我使用动态查询,但我们改为预编译查询。没有动态查询还有其他解决方案吗?
    • @Siva 。 . .解决方案是多次重复查询 if @sortColumn = . . . begin select . . . order by CustomerName asc end else if 。 . . `。我不建议重复查询。它变成了维护的噩梦。
    猜你喜欢
    • 2012-07-25
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 2019-04-13
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多