Row_Number() OVER 的用法


在項目中遇見當數據量達到千萬級的時候分頁與查詢數據出現性能問題,時常出現timeout現象。

要求,查詢出某個地區在某種類型下相應子類型最近一天的的報價信息,如果采用把某個地區的某種類型下的所有子類型的最近一天報價相應信息與日期放到臨時表中,然后再歷史報價表中查詢相應的最近日期,會出現timeout:

現在做如下修改:

修改后
 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

調用端:

調用段
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()時常用在分頁中。

分頁
 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 是數據的分區取數,用於給結果集分組,如果沒有指定那么它把整個結果集作為一個分組,它和聚合函數不同的地方在於它能夠返回一個分組中的多條記錄,而聚合函數一般只有一個反映統計值的記錄。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM