替代使用ROW_NUMBER以获得更好的效果

时间:2016-10-30 22:57:56

标签: sql sql-server

我在下面有一个小查询,它根据对“LegKey”列进行分区并按UpdateID desc排序,在RowNumber列下输出行号。这样每个legkey的最新更新行(UpdateID)始终为1

SELECT *
, ROW_NUMBER() OVER(PARTITION BY LegKey ORDER BY UpdateID DESC) AS RowNumber 
FROM Data.Crew

输出数据:

UpdateID    LegKey  OriginalSourceTableID   UpdateReceived          RowNumber
7359        6641    11                     2016-08-22 16:35:27.487  1
7121        6641    11                     2016-08-15 00:00:47.220  2
8175        6642    11                     2016-08-22 16:35:27.487  1
7122        6642    11                     2016-08-15 00:00:47.220  2
8613        6643    11                     2016-08-22 16:35:27.487  1
7123        6643    11                     2016-08-15 00:00:47.220  2

我对这种方法的问题是我的性能变慢,因为我假设我使用的是ORDER BY。

我的问题是,有没有另一种方法来产生类似的结果,但我的查询运行得更快?我在想MAX()可能有用,但我没有得到与以前相同的输出。也许我的MAX()语句不正确,所以想知道如果有人可以提供一个关于他们如何为这个例子编写MAX()语句的例子,这是否是一个很好的选择?

谢谢

2 个答案:

答案 0 :(得分:2)

据推测,这是您要优化的查询:

SELECT c.*
FROM (SELECT c.*,
             ROW_NUMBER() OVER (PARTITION BY LegKey ORDER BY UpdateID DESC) AS RowNumber 
      FROM Data.Crew c
     ) c
WHERE RowNumber = 1;

Crew(LegKey, UpdateId)上尝试索引。

如果您执行以下操作,也将使用此索引:

SELECT c.*
FROM Data.Crew c
WHERE c.UpdateId = (SELECT MAX(c2.UpdateId)
                    FROM Data.Crew c2
                    WHERE c2.LegKey = c.LegKey
                   );

答案 1 :(得分:0)

您可以尝试以下方法之一:

ipc.on('...', (evt, status) => {
  setTimeout(() => {
    ...
  });
});

这里使用子查询中的MAX Date。

declare @Table table(UpdateID int,   LegKey int,  OriginalSourceTableID int,  UpdateReceived datetime)

您可以在cte with group by中使用它。

select * from @Table as a where a.UpdateReceived = (Select MAX(UpdateReceived) from @Table as b Where b.LegKey = a.LegKey)