`
蔡华江
  • 浏览: 106107 次
  • 性别: 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条件一大砣又不是按索引列排序(按最后操作时间,没法加索引)。

相关推荐

    oracle中rownum和row_number()

    主要介绍了oracle中rownum和row_number()的使用方法以及区别和联系,十分的详细,有需要的小伙伴可以参考下。

    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 **),有时我根本就...

    Oracle数据库rownum和row_number的不同点

    在Oracle中,有一个很有趣的东西,那就是rownum。当你从某个表中查询数据的时候,返回的结果集中都会带有rownum这个字段,而且有时候也可以使用rownum进行一些条件查询

    SQL学习笔记八 索引,表连接,子查询,ROW_NUMBER

    索引 经常要查询的语句,则给它建一个索引 表连接 select T_Oders as o join T_Customers as C on o.CustomerId = c.Id 子查询 单值子查询 单列多值子查询 ROW_NUMBER()函数 ROW_NUMBER() OVER(ORDER BY Fsalary ...

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

    row_number()和rownum差不多,功能更强一点(可以在各个分组内从1开始排序)。 rank()是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内) dense_rank()也是连续排序,有两个第二名时仍然跟

    利用ROW_NUMBER() OVER函数给SQL数据库中每一条记录分配行号的方法

    从SQL Server 2005开始,增加了一个新的函数Row_Number(),他的一个很伟大的作用就是可以在数据表中添加一列从1...SELECT ROW_NUMBER() OVER(ORDER BY id) as rowNum,* FROM 表名称 代码如下: rowNum id name 1 

    Oracle 分析函数RANK(),ROW_NUMBER(),LAG()等的使用方法

    是第3名 LAG 表示 分组排序后 ,组内后面一条记录减前面一条记录的差,第一条可返回 NULL BTW: EXPERT ONE ON ONE 上讲的最详细,还有很多相关特性,文档看起来比较费劲 row_number()和rownum差不多,功能更强一点...

    Oracle中使用Rownum分页详细例子

    主要介绍了Oracle中使用Rownum分页详细例子,本文将分别展示使用rownum伪列和row_number()分析函数来完成Oracle数据分页操作的具体使用方法,需要的朋友可以参考下

    SqlServer 2005中使用row_number()在一个查询中删除重复记录

    在SqlServer2005中,提供了一个row_number()的函数,我们经常用它做DataBase数据分页.

    Oracle开发之分析函数(Rank, Dense_rank, row_number)

    一、使用rownum为记录排名: 在前面一篇《Oracle开发之分析函数简介Over》,我们认识了分析函数的基本应用,现在我们再来考虑下面几个问题: ①对所有客户按订单总额进行排名 ②按区域和客户订单总额进行排名 ③找出...

    SQL行号排序和分页(SQL查询中插入行号 自定义分页的另类实现)

    SELECT * FROM #1 B.SQL 2005提供一个很好用的函数row_number(), 可以直接用来显示行号,当然也可以使用SQL 2000的identity SELECT row_number()over(ORDER BY DataID) AS ROWNUM, [DataID] FRO

    MySQL中在查询结果集中得到记录行号的方法

    如果需要在查询语句返回的列中包含一列表示该条记录在整个结果集中的行号, ISO SQL:2003 标准提出的方法是提供 ROW_NUMBER() / RANK() 函数。 Oracle 中可以使用标准方法(8i版本以上),也可以使用非标准的 ROWNUM...

    Sql Server 的SQL语句案例

    有完整的案例SQL语句,直接拷贝运行。... SELECT ROW_NUMBER() OVER(ORDER BY FSalary DESC) AS rownum, FNumber,FName,FSalary,FAge FROM T_Employee ) AS a WHERE a.rownum&gt;=3 AND a.rownum&lt;=5

    sql2005 根据指定字段排序编号

    SQL语句如下: 代码如下:WITH 表1 AS ( SELECT 编号字段名, ROW_NUMBER() OVER(ORDER BY 排序字段名 DESC) AS RowNum FROM 表名 ) Update 表1 SET 编号字段名=RowNum 应用场景: 通过这样的SQL语句根据小组人气值对...

    高效的通用分页存储过程

    'select row_number() over (order by ' + @strSort + ') as RowNum ,' + @fldName + ' from ' + @tblName + ') a where a.RowNum &gt; ' + cast((@page -1) * @pageSize as varchar(128)) + ' and a.RowNum (@...

    分页存储过程

    alter proc usp_Fen ... select top (@tiaoshu) * from (select *,ROW_NUMBER() over(order by fid asc ) as rownum from MyStudent ) as t where t.rownum between @tiaoshu*(@yema-1)+1 and @tiaoshu*@yema end

    SQL分页查询方式汇总

    需求:查询表dbo.Message,每页...2:BETWEEN * AND * , Row_Number() OVER(ORDER BY *) AS rowNum SELECT *,ROW_NUMBER() OVER(ORDER BY Code) AS rowNum INTO #a FROM dbo.Message SELECT * FROM #a WHERE rowNum BE

Global site tag (gtag.js) - Google Analytics