使用 order by 时的动态 order by - 加速
我正在使用行号从存储过程获取分页结果。
我发现使用动态 case 语句列名称进行排序会减慢速度 - 但如果我按一切硬编码顺序就可以了。
有没有一种方法可以通过不使整个 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]
I am using row number to get paged results back from a stored procedure.
I am finding that ordering using a dynamic case statement column name is slowing things down - but if I hardcode the order by everything is ok.
Is there a way to speed up the dynamic order by without making the WHOLE sql query one string and using 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]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题在于 SQL Server 正在尝试构建一个执行计划来适应所有参数。这意味着当您给它不同的参数时,它不会改变主意并选择不同的索引。 (
不同索引
部分很重要,因为对不适当的索引重新排序的负载可能非常高。)实现这种情况的唯一方法是生成新的执行计划,这涉及动态 SQL - 这正是您想要避免的。
但是;动态 SQL 和 SP_EXECUTESQL 不一定是坏主意。由于它也可以参数化,正确使用确实允许执行计划重用,并且可以非常有效地解决此类问题。
是否有特定原因需要避免动态 SQL?
唯一实际的解决办法是多次以不同的顺序编写查询,然后选择与 T 一起使用的查询-SQL
IF
块。这将允许优化器生成不同的执行计划。The problem is that SQL Server is trying to build ONE execution plan to fit all parameters. This means that it doesn't change it's mind and pick a different index when you give it different parameters. (The
different index
part is important as the load of re-ordering an inappropriate index can be very high.)The only way for that to happen is to generate a new execution plan, and that involves dynamic SQL - Exactly what you want to avoid.
However; dynamic SQL and SP_EXECUTESQL is not necessarily a bad idea. As it can also be parametrised, correct use does allow execution plan re-use and can be exceptionally efficient at these kinds of problems.
Is there specific reason that you need to avoid dynamic SQL?
The only realistic work around is to have the query written out multiple times, with the different ordering, and pick which one to use with T-SQL
IF
blocks. This will allow the optimiser to generate the varying execution plans.SQL Server 不支持单个查询根据参数值使用不同的索引。 AFAIK,有两种解决方案:
在实践中,PHP 和 .NET 应用程序很难共享代码。或者甚至针对不同的 .NET 版本。这使得第一个选项成为更强的选择。
因此,最好的方法是使用动态 SQL。是的,这非常令人惊讶。 :)
Having a single query use different indexes based on parameter values is not supported in SQL Server. AFAIK, there are two solutions to this:
sp_executesql
In practice, it's hard for a PHP and a .NET application to share code. Or even for different .NET versions. That makes the first option the stronger choice.
So the best way to do this involves dynamic SQL. And yeah that's pretty surprising. :)
您可以尝试的一件事是将两个 case 子句合并为一个 case - 像这样:
显然,如果某些潜在的排序值是字符串而不是数字,则这种方法不实用。
One thing you could try would be to combine your two case clauses into a single case - like this:
Obviously, this approach would not be practical if some of your potential sort values are strings instead of numbers.
尝试多个 ROW_NUMBER 语句,以便减少每次排序的处理量
Try multiple ROW_NUMBER statements so you have less processing per sort