oracle两表查询分页,Oracle分页查询语句(二)

这篇文章用几个例子来说明分页查询的效率。首先构造一个比较大的表作为测试表:

SQL> CREATE TABLE T AS SELECT * FROM DBA_OBJECTS, DBA_SEQUENCES;

表已创建。

SQL> SELECT COUNT(*) FROM T;

COUNT(*)

----------

457992

首先比较两种分页方法的区别:

SQL> SET AUTOT ON

SQL> COL OBJECT_NAME FORMAT A30

SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T')

PL/SQL 过程已成功完成。

SQL> SELECT OBJECT_ID, OBJECT_NAME

2 FROM

3 (

4 SELECT ROWNUM RN, OBJECT_ID, OBJECT_NAME

5 FROM

6 (

7 SELECT OBJECT_ID, OBJECT_NAME FROM T

8 )

9 )

10 WHERE RN BETWEEN 11 AND 20;

OBJECT_ID OBJECT_NAME

---------- ------------------------------

5807 ALL_APPLY_PROGRESS

1769 ALL_ARGUMENTS

2085 ALL_ASSOCIATIONS

4997 ALL_AUDIT_POLICIES

4005 ALL_BASE_TABLE_MVIEWS

5753 ALL_CAPTURE

5757 ALL_CAPTURE_PARAMETERS

5761 ALL_CAPTURE_PREPARED_DATABASE

5765 ALL_CAPTURE_PREPARED_SCHEMAS

5769 ALL_CAPTURE_PREPARED_TABLES

已选择10行。

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT ptimizer=CHOOSE (Cost=864 Card=457992 Bytes=42135264)

1 0 VIEW (Cost=864 Card=457992 Bytes=42135264)

2 1 COUNT

3 2 TABLE ACCESS (FULL) OF 'T' (Cost=864 Card=457992 Bytes=9617832)

Statistics

----------------------------------------------------------

0 recursive calls

0 db block gets

8979 consistent gets

7422 physical reads

0 redo size

758 bytes sent via SQL*Net to client

503 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

10 rows processed

SQL> SELECT OBJECT_ID, OBJECT_NAME

2 FROM

3 (

4 SELECT ROWNUM RN, OBJECT_ID, OBJECT_NAME

5 FROM

6 (

7 SELECT OBJECT_ID, OBJECT_NAME FROM T

8 )

9 WHERE ROWNUM <= 20

10 )

11 WHERE RN >= 11;

OBJECT_ID OBJECT_NAME

---------- ------------------------------

5807 ALL_APPLY_PROGRESS

1769 ALL_ARGUMENTS

2085 ALL_ASSOCIATIONS

4997 ALL_AUDIT_POLICIES

4005 ALL_BASE_TABLE_MVIEWS

5753 ALL_CAPTURE

5757 ALL_CAPTURE_PARAMETERS

5761 ALL_CAPTURE_PREPARED_DATABASE

5765 ALL_CAPTURE_PREPARED_SCHEMAS

5769 ALL_CAPTURE_PREPARED_TABLES

已选择10行。

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT ptimizer=CHOOSE (Cost=864 Card=20 Bytes=1840)

1 0 VIEW (Cost=864 Card=20 Bytes=1840)

2 1 COUNT (STOPKEY)

3 2 TABLE ACCESS (FULL) OF 'T' (Cost=864 Card=457992 Bytes=9617832)

Statistics

----------------------------------------------------------

0 recursive calls

0 db block gets

5 consistent gets

0 physical reads

0 redo size

758 bytes sent via SQL*Net to client

503 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

10 rows processed

二者执行效率相差很大,一个需要8000多逻辑读,而另一个只需要5个逻辑读。观察二者的执行计划可以发现,两个执行计划唯一的区别就是第二个查询在COUNT这步使用了STOPKEY,也就是说,Oracle将ROWNUM <= 20推入到查询内层,当符合查询的条件的记录达到STOPKEY的值,则Oracle结束查询。

因此,可以预见,采用第二种方式,在翻页的开始部分查询速度很快,越到后面,效率越低,当翻到最后一页,效率应该和第一种方式接近。

SQL> SELECT OBJECT_ID, OBJECT_NAME

2 FROM

3 (

4 SELECT ROWNUM RN, OBJECT_ID, OBJECT_NAME

5 FROM

6 (

7 SELECT OBJECT_ID, OBJECT_NAME FROM T

8 )

9 WHERE ROWNUM <= 457990

10 )

11 WHERE RN >= 457980;

OBJECT_ID OBJECT_NAME

---------- ------------------------------

7128 XCF_I_HANDLE_STATUS

7126 XCF_P

7127 XCF_U1

7142 XDF

7145 XDF_I_DF_KEY

7146 XDF_I_HANDLE_STATUS

7143 XDF_P

7144 XDF_U1

TEST.YANGTINGKUN

TEST4.YANGTINGKUN

YANGTK.YANGTINGKUN

已选择11行。

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT ptimizer=CHOOSE (Cost=864 Card=457990 Bytes=42135080)

1 0 VIEW (Cost=864 Card=457990 Bytes=42135080)

2 1 COUNT (STOPKEY)

3 2 TABLE ACCESS (FULL) OF 'T' (Cost=864 Card=457992 Bytes=9617832)

Statistics

----------------------------------------------------------

0 recursive calls

0 db block gets

8979 consistent gets

7423 physical reads

0 redo size

680 bytes sent via SQL*Net to client

503 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

11 rows processed

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值