SQL 服务器条件排序性能问题

SQL Server Conditional Sort Performance Issue

我有一个 table,它有大约 500 万行。当我尝试对此 table 进行条件排序时,它需要大约 25 秒,但是当我将条件排序更改为特定排序标准时,它需要 1 秒。唯一的区别如下;

--takes 1 second
ROW_NUMBER() OVER (ORDER BY OrderId DESC) AS RowNumber 

--takes around 25 seconds
CASE @SortColumn WHEN 'OrderId' THEN ROW_NUMBER() OVER (ORDER BY OrderId DESC) AS RowNumber 

谁能解释一下 SQL 服务器在这种情况下发生了什么?

OrderId 必须被索引。因此在第一个实例中:

ROW_NUMBER() OVER (ORDER BY OrderId DESC) AS RowNumber 

SQL 不需要执行排序,因为最初对 OrderId 列执行了索引扫描。它知道索引是按您要排序的列排序的,因此不需要执行其他排序。

但是在第二个示例中,SQL 必须为每一行计算 CASE @SortColumn WHEN 'OrderId' THEN ROW_NUMBER() OVER (ORDER BY OrderId DESC) END。因此,它对每一行执行计算标量运算以计算出 CASE 语句的结果。此操作的结果无法映射到索引,因为它们不代表列并且需要进一步的排序操作。超过 500 万行,这是一个非常昂贵的操作。

如果您要 运行 对 non-indexed 列的查询:

--takes 25 second
ROW_NUMBER() OVER (ORDER BY NonIndexedColumn DESC) AS RowNumber 

--takes around 25 seconds
CASE @SortColumn WHEN 'NonIndexedColumn' THEN ROW_NUMBER() OVER (ORDER BY NonIndexedColumn DESC) AS RowNumber

那么这两个查询可能 运行 同样慢,因为 SQL 必须在两个实例中进行排序(而不仅仅是使用排序索引)。因此,如果有人选择 non-indexed 列,则传入列进行排序总是会导致大量行的性能下降。因此,您需要确保在应用 ORDER BY 之前将结果过滤到可管理的行数。