`
蔡华江
  • 浏览: 107624 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

ROWNUM与ROW_NUMBER()

阅读更多

      主要是在网上看到了一些关于排序分页的帖子,个人感觉有些不妥,就写出SQL进行了测试下,下面列出结果与看法。

 

      通常先排序再分页都是使用ROWNUM伪列,通过将查询结果先进行排序,再使用两层SQL将查询结果进行分页,例子如:

SELECT *
  FROM (SELECT ROWNUM row_, t.*
          FROM (SELECT   *
                    FROM fltk
                ORDER BY ID) t
         WHERE ROWNUM < 10)
 WHERE row_ >= 0

      执行计划:

--------------------------------------------------
| Id  | Operation                      | Name    |
--------------------------------------------------
|   0 | SELECT STATEMENT               |         |
|   1 |  VIEW                          |         |
|   2 |   COUNT STOPKEY                |         |
|   3 |    VIEW                        |         |
|   4 |     TABLE ACCESS BY INDEX ROWID| FLTK    |
|   5 |      INDEX FULL SCAN           | PK_FLTK |
--------------------------------------------------

 

      还有一种排序分页的做法是使用分析函数ROW_NUMBER(),有人认为这种实现方法更加的高效。以下是SQL语句,实现的目标结果完全相同。

SELECT *
  FROM (SELECT ROW_NUMBER () OVER (ORDER BY ID) row_, fltk.*
          FROM fltk)
 WHERE row_ >= 0 AND row_ < 10;

      执行计划:

-----------------------------------------
| Id  | Operation                | Name |
-----------------------------------------
|   0 | SELECT STATEMENT         |      |
|   1 |  VIEW                    |      |
|   2 |   WINDOW SORT PUSHED RANK|      |
|   3 |    TABLE ACCESS FULL     | FLTK |
-----------------------------------------

 

      查询的数据量是100万条,最后的结果是使用ROWNUM来查询为16ms左右,而使用ROW_NUMBER()来进行查询需要1s,通过执行计划分析,ROWNUM中使用了索引,而ROW_NUMBER没有使用索引,这是导致两者性能差别最大的地方。

      然后使用没有索引的列进行排序,最后的结果是两者都需要1s,性能差异不大。

      由于性能差异不明显,体现不出两者的差别,于是将检索范围做了调整,如下图所示:


      由上可见,无论是在对数据量前面开始进行分页,还是选择分页后面的的结果,还是分页中的每页的内容都很多,这两者在查询效率上都没有很明显的差异,但是当对有索引列进行排序的时候,ROWNUM有着很明显的优势。

  • 大小: 16.4 KB
分享到:
评论
4 楼 Eric.Yan 2012-05-31  
学习了
但是有一个问题哈,‘ROWNUM中使用了索引’,自带的索引还是人为加上去的索引?
3 楼 miaow 2009-12-17  
我之前说差50%的数据量还没有百万,大概二三十万行的样子。
这套分组函数,多数用索引会很奇怪,特别是加上partition by之后。可能为此就统一先取进来了再处理了。
如果是都先取进来,加个排序值伪列比要排序的order by性能好一点也不奇怪啊。
2 楼 蔡华江 2009-12-17  
可能是百万级的数据量实在太少了,还不足以突出两者的性能差异。
而row_number()不能使用索引实在是个问题,不知道是不是使用索引有什么限制条件?
1 楼 miaow 2009-12-17  
我印象里以前在实际项目中测过,row_number()有一定性能优势,大约高50%的样子。
你分析的用到索引的差异,可能有些关系。
你的场景是没有where条件又刚好有一个可以用的索引。
我用到的场景都是where条件一大砣又不是按索引列排序(按最后操作时间,没法加索引)。

相关推荐

    SQL ROW_NUMBER()分页比较

    select row_number() over(order by name) as rowNum,* from users ) as t where rowNum between 5000 and 5100 ``` 这种方法的缺点是需要查出所有数据,然后再进行排序和过滤,这将导致性能问题。 正确的使用...

    ROW_NUMBER、RANK、DENSE_RANK 和 NTILE

    SELECT ROW_NUMBER() OVER(ORDER BY score DESC) AS rownum, speaker, track, score FROM SpeakerStats ``` rownum speaker track score ------ ------ ------ ----- 1 Jessica Dev 9 2 Ron Dev 9 3 Suzanne DB 9 4...

    Oracle数据库rownum和row_number的不同点

    与 `ROWNUM` 不同,`ROW_NUMBER()` 可以在 `WHERE` 子句中配合使用,允许我们更灵活地筛选特定行范围,例如选取第n到第m行的数据: ```sql SELECT * FROM ( SELECT ename, sal, ROW_NUMBER() OVER (ORDER BY sal ...

    oracle中rownum和row_number()

    与rownum的区别在于:使用rownum进行排序的时候是先对结果集加入伪劣rownum然后再进行排序,而row_number()在包含排序从句后是先排序再计算行号码。 一、oracle中rownum 用于从查询返回的行的编号,返回的第一行...

    Row_number 分页存储过程

    例如,你可以创建一个名为`Pager_Rownumber`的存储过程,如下所示: ```sql CREATE PROCEDURE Pager_Rownumber @PageNumber INT, @PageSize INT, @OrderColumn NVARCHAR(128), @TableName NVARCHAR(128) AS ...

    深入探讨:oracle中row_number() over()分析函数用法

    with row_number_test as ( select 22 as a, 'twenty two' as b from dual union all select 1, 'one' from dual union all select 13, 'thirteen' from dual union all select 5, 'five' from dual union all ...

    sqlServer使用ROW_NUMBER时不排序的解决方法

    [sql] with query as (select ROW_NUMBER() over(order by (select 0)) AS ROWNUM, * FROM Product) select * from query where ROWNUM BETWEEN 5 AND 10 –2.ROW_NUMBER必须指写over (order by **),有时我根本就...

    SQL Server 2005中ROW_NUMBER()函数在存储过程分页中的应用.pdf

    SELECT ROW_NUMBER() OVER (ORDER BY column_name(s)) AS RowNum, * FROM table_name; ``` 在这个语句中,`OVER`子句定义了排序的逻辑,`ORDER BY`则指定了排序的依据。`RowNum`是生成的新列,包含了每一行的序列号...

    oracle rownum 的使用 和sqlserver有区别的!

    - 在 SQL Server 中,ROW_NUMBER() 函数与 Oracle 中的 ROWNUM 功能类似,但它们之间存在一些关键差异。 - **ROW_NUMBER()** 可以基于特定的排序规则为每行分配一个连续的数字,这使得它在处理有序数据时更为灵活...

    sqlserver 通用存储过程分页代码(附使用ROW_NUMBER()和不使用ROW_NUMBER()两种情况性能分析)

    SET @sql = 'SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY ' + @strOrder + ') AS RowNum FROM ' + @tblName IF (@strWhere != '') SET @sql = @sql + ' WHERE ' + @strWhere SET @sql = @sql + ') ...

    ROW_NUMBER SQL Server 2005的LIMIT功能实现(ROW_NUMBER()排序函数)

    SELECT ROW_NUMBER() OVER(ORDER BY id ASC) AS rownum, * FROM MyTable ) AS items WHERE items.rownum BETWEEN 20 AND 30; ``` 2. **按价格升序排序**:在 `OP_Order` 表中,按 `totalPrice` 排序并编号:...

    Oracle row_number() over()解析函数高效实现分页

    因此,如果我们先`ORDER BY`再使用`ROWNUM`,行号可能会与预期的顺序不一致。 例如,如果我们尝试这样的查询: ```sql SELECT ROWNUM r, t.* FROM t_news t WHERE ROWNUM &lt;= 3 ORDER BY t.n_count DESC ``` 行号将...

    使用row_number()实现分页实例

    `ROW_NUMBER()`函数在SQL Server中被广泛用于实现分页,因为它可以为查询结果集中的每一行分配一个唯一的行号。以下是对使用`ROW_NUMBER()`实现分页的详细解释。 首先,我们来看提供的代码片段: ```sql create ...

    MYSQL获取行号row_no

    在数据库操作中,有时候我们需要为查询结果集中的每一行添加一个行号(或行序号),类似于Oracle中的`ROW_NUMBER()`功能。然而MySQL并未直接提供与Oracle完全相同的功能,因此我们需要通过其他方式来实现这一需求。...

    SQL中row-number函数用法

    ### SQL中row_number函数详解与应用 #### 一、row_number函数概述 `row_number()` 是SQL中的一个重要窗口函数,用于为每一行分配一个唯一且连续的整数。这一功能在处理复杂的数据排序和筛选场景时非常有用。下面将...

    SQL server中row_number(),rank(),dense_rank()排序

    SELECT Sno, Cno, Grade, ROW_NUMBER() OVER (ORDER BY Grade DESC) AS RowNum FROM SC; ``` 上述查询将按照Grade降序为每一行分配一个RowNum,成绩越高,编号越小。 2. `rank()` `rank()` 函数也返回一个唯一的...

Global site tag (gtag.js) - Google Analytics