SQL Server - Order by case 语句非常慢

izi*_*zip 4 sql-server t-sql

我在执行正常的 SP 中有以下查询:

SELECT * FROM MyTable u
ORDER BY 
u.[Id] DESC
OFFSET @PageSize * (@PageNumber - 1) ROWS
FETCH NEXT @PageSize ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

但是,当我从 SP 参数配置 ORDER BY 时,查询从以毫秒为单位执行到几秒:

SELECT * FROM MyTable u
ORDER BY 
CASE WHEN @Sort = 0 THEN u.[Id] END DESC,
CASE WHEN @Sort = 1 THEN u.[Id] END ASC,
CASE WHEN @Sort = 2 THEN u.[LastName] END ASC,
CASE WHEN @Sort = 3 THEN u.[LastName] END DESC
OFFSET @PageSize * (@PageNumber - 1) ROWS
FETCH NEXT @PageSize ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

即使订单使用相同的字段,现在放缓的原因是什么?(ID DESC?)

有没有办法让这个表现更好?

我在 SQL Server 2016 和 SQL Azure 中尝试过。

编辑:没有案例排序的执行计划/实时统计:

无案例订购 执行计划没问题

带有案例排序的执行计划/实时统计信息:

这是使用 case 语句的执行计划 执行计划

Seb*_*ine 12

任何计算或函数,当应用于索引键列时,都会阻止 SQL Server 使用该索引。

在您的情况下,ORDER BY Id DESC可以使用表上聚集索引的有序扫描,就像Id该索引上的键列一样。这意味着,只需读取 20 行。

一旦应用了该CASE语句,SQL Server 就不能再使用该索引,而是必须扫描整个行集并对所有行执行(非常昂贵)排序以找到您感兴趣的 20 行。

解决方案之一是使用动态 SQL 来包含适当的ORDER BY而不进行任何计算(正如拉马克在上面的评论中所建议的那样),或者只编写 4 次查询并使用IF语句来决定执行哪一个。