Sql 性能改进外部应用

Sql 性能改进外部应用,sql,sql-server,Sql,Sql Server,我有一个运行较慢的查询 SELECT * FROM [Obe].[dbo].[vFan] P OUTER APPLY (SELECT TOP 1 [CT_XY] FROM [Obe].[dbo].[vFan] WHERE [row_num] <= P.[row_num] AND [CT_XY] IS NOT NULL AND [CT_XY] != 0 ORDER BY [row_num] DESC) Q OUT

我有一个运行较慢的查询

SELECT * 
FROM [Obe].[dbo].[vFan] P 
OUTER APPLY
    (SELECT TOP 1 [CT_XY] 
     FROM [Obe].[dbo].[vFan] 
     WHERE [row_num] <= P.[row_num] 
       AND [CT_XY] IS NOT NULL 
       AND [CT_XY] != 0 
     ORDER BY [row_num] DESC) Q
OUTER APPLY
    (SELECT TOP 1 [CT_CR1]  
     FROM [Obe].[dbo].[vFan] 
     WHERE [row_num] <= P.[row_num] 
       AND [CT_CR1] IS NOT NULL 
       AND [CT_CR1] != 0 
     ORDER BY [row_num] DESC) R
OUTER APPLY
    (SELECT TOP 1 [CT_CR2] 
     FROM [Obe].[dbo].[vFan] 
     WHERE [row_num] <= P.[row_num] 
       AND [CT_CR2] IS NOT NULL 
       AND [CT_CR2] != 0 
     ORDER BY [row_num] DESC) S
ORDER BY 
    P.[row_num] ASC
外部应用程序内部的Order By非常昂贵,是否有更好的方法编写此查询?

当您使用Order By时,SQL Server必须计算所有行,然后进行排序,只有这样,它才能提供您所需的行

因此,为WHERE语句中使用的字段(如CT_XY、CT_CR1、CT_CR2)添加索引将非常有用

更新:


您不应该向视图添加索引,有必要向基础表添加索引。在适当的情况下,查询将在视图本身引用的基础表上使用索引

从代码中可以看出,您似乎实现了一个lagnore nulls的变体

这里有一个更好的方法:

select f.*,
       max(ct_xy) over (partition by rn_xy) as new_ct_xy,
       max(rn_cr1) over (partition by rn_cr1) as new_rn_cr1,
       max(rn_cr2) over (partition by rn_cr2) as new_rn_cr2
from (select f.*,
             sum(case when CT_XY is not null and CT_XY <> 0 
                      then row_num
                 end) over (order by row_num) as rn_xy,
             sum(case when CT_CR1 is not null and CT_CR1 <> 0 
                      then row_num
                 end) over (order by row_num) as rn_cr1,
             sum(case when CT_CR2 is not null and CT_CR2 <> 0 
                      then row_num
                 end) over (order by row_num) as rn_cr2
      from vfan f 
     ) f;

还请注意,在许多数据库中,vfan中的v会建议一个视图。这可能是性能问题的原因。

因为它是一个视图列,所以我无法创建索引。CT_XY、CT_CR1、CT_CR2列是在运行时在视图中计算和创建的。不存在于父项中table@Jayasree正如Gordon Linoff所说的示例数据,期望的结果和逻辑的解释都会有帮助示例数据,期望的结果和逻辑的解释都会有帮助lag@Jayasree . . . 它应该为每一行取上一个有效值。但是,如果您设置了一个dbfiddle,我就可以更好地了解您的数据以及您想要什么。