Row_Number() OVER 的用法

在项目中遇见当数据量达到千万级的时候分页与查询数据出现性能问题,时常出现timeout现象。

要求,查询出某个地区在某种类型下相应子类型最近一天的的报价信息,如果采用把某个地区的某种类型下的所有子类型的最近一天报价相应信息与日期放到临时表中,然后再历史报价表中查询相应的最近日期,会出现timeout:

现在做如下修改:

Row_Number() OVER 的用法 修改后
 1 CREATE PROC [dbo].[usp_GetHistoryPrices]

 2 @AreaID    INT,

 3 @TypeID    INT

 4 AS

 5 BEGIN

 6     SET NOCOUNT ON;

 7     WITH temp_1 AS(

 8         SELECT ss.*,ROW_NUMBER() OVER(PARTITION BY AreaID,GoodsID Order by PriceDate DESC) AS pn FROM MD_HistoryPrices ss 

 9         INNER JOIN MD_Goods gg ON ss.GoodsId = gg.ID AND GG.TypeId = @TypeID AND gg.IsDelete= 0 and AreaID = @AreaID

10     )

11     SELECT * FROM   temp_1 WHERE  pn=1 

12 END

调用端:

Row_Number() OVER 的用法 调用段
1 DECLARE @AreaID    INT;

2 DECLARE @TypeID    INT;

3 SET @AreaID = 1;

4 SET @TypeID = 1;

5 EXEC [usp_GetHistoryPrices] @AreaID,@TypeID

此时查询效率提高。

采用方式,针对地区和子类型进行分组,排序,同时给每个地区,子类型,报价日期进行编号,当pn=1时候就代表是相应地区与子类型最近一天的报价。

另外,Row_Number() over()时常用在分页中。

Row_Number() OVER 的用法 分页
 1  CREATE PROC [dbo].[usp_Page]

 2  @PageIndex INT,

 3  @PageSize INT,

 4  @TypeID    INT,

 5  @AreaID    INT

 6  AS

 7  BEGIN

 8    SET NOCOUNT ON;

 9     WITH TEMP_1 AS(

10       SELECT ss.*,ROW_NUMBER () OVER( ORDER BY ss.ID DESC) AS pn FROM  MD_HistoryPrices ss INNER JOIN MD_Goods gg ON gg.TypeId =@TypeID 

11       AND gg.ID =ss.GoodsId AND ss.AreaID=@AreaID

12     )

13     SELECT * FROM TEMP_1 WHERE pn>@PageIndex*@PageSize AND pn<=(@PageIndex +1)*@PageSize

14  END

15  


在使用 row_number() over()函数时候,over()里头的分组以及排序的执行晚于 where group by  order by 的执行。

partition by 是数据的分区取数,用于给结果集分组,如果没有指定那么它把整个结果集作为一个分组,它和聚合函数不同的地方在于它能够返回一个分组中的多条记录,而聚合函数一般只有一个反映统计值的记录。

 

 

你可能感兴趣的:(row_number())