4

我正在使用行号从存储过程中获取分页结果。

我发现使用动态案例语句列名进行排序会减慢速度 - 但如果我按所有内容对订单进行硬编码,则一切正常。

有没有一种方法可以通过不使整个 sql 查询一个字符串并使用 SP_EXECUTESQL 来加快动态顺序

            ROW_NUMBER() OVER (ORDER BY 
            CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending  = 0 THEN CLH.IdentityValue END DESC,
            CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending  = 1 THEN CLH.IdentityValue END
            --CLH.CustomerName

            ) AS [ROW]
4

4 回答 4

1

问题是 SQL Server 正在尝试构建一个执行计划以适应所有参数。这意味着当您给它不同的参数时,它不会改变主意并选择不同的索引。(这different index部分很重要,因为重新排序不合适的索引的负载可能非常高。)

发生这种情况的唯一方法是生成一个新的执行计划,这涉及到动态 SQL——这正是你想要避免的。


然而; 动态 SQL 和 SP_EXECUTESQL 不一定是个坏主意。由于它也可以参数化,因此正确使用确实允许重复使用执行计划,并且在此类问题上可能非常有效。

是否有特定原因需要避免使用动态 SQL?


唯一现实的解决方法是多次写出查询,使用不同的顺序,然后选择要与 T-SQLIF块一起使用的查询。这将允许优化器生成不同的执行计划。

于 2011-12-13T12:39:52.477 回答
1

SQL Server 不支持单个查询根据参数值使用不同的索引。AFAIK,有两种解决方案:

  • 在存储过程中构建动态查询并使用sp_executesql
  • 构建动态查询客户端

实际上,PHP 和 .NET 应用程序很难共享代码。甚至适用于不同的 .NET 版本。这使得第一个选项成为更强的选择。

因此,最好的方法是使用动态 SQL。是的,这非常令人惊讶。:)

于 2011-12-13T12:57:09.363 回答
0

尝试多个 ROW_NUMBER 语句,这样每次排序的处理量就会减少

   ROW_NUMBER() OVER (ORDER BY CLH.IdentityValue) DESC AS rnDesc,
   ROW_NUMBER() OVER (ORDER BY CLH.IdentityValue) AS rnAscDesc,
   ...
ORDER BY
   CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending  = 0 THEN rnDesc END,
   CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending  = 1 THEN rnDesc END
于 2011-12-13T14:50:46.583 回答
0

您可以尝试的一件事是将您的两个案例子句组合成一个案例 - 如下所示:

(ORDER BY 
        CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending  = 0 
                 THEN CLH.IdentityValue*-1
             WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending  = 1 
                 THEN CLH.IdentityValue 
        END
 )

显然,如果您的某些潜在排序值是字符串而不是数字,那么这种方法将不实用。

于 2011-12-13T12:56:16.170 回答