Oracle分頁查詢格式(十)

路途中的人2012發表於2017-06-21

Oracle的分頁查詢語句基本上可以按照本文給出的格式來進行套用。

Oracle分頁查詢格式(一):http://yangtingkun.itpub.net/post/468/100278

Oracle分頁查詢格式(二):http://yangtingkun.itpub.net/post/468/101703

Oracle分頁查詢格式(三):http://yangtingkun.itpub.net/post/468/104595

Oracle分頁查詢格式(四):http://yangtingkun.itpub.net/post/468/104867

Oracle分頁查詢格式(五):http://yangtingkun.itpub.net/post/468/107934

Oracle分頁查詢格式(六):http://yangtingkun.itpub.net/post/468/108677

Oracle分頁查詢格式(七):http://yangtingkun.itpub.net/post/468/109834

Oracle分頁查詢格式(八):http://yangtingkun.itpub.net/post/468/224557

Oracle分頁查詢格式(九):http://yangtingkun.itpub.net/post/468/224409


Oracle10g的新功能GROUP BY STOPKEY,使得Oracle10g解決了上一篇文章中提到的GROUP BY操作無法分頁的問題。

在10g以前,OracleGROUP BY操作必須完全執行完,才能將結果返回給使用者。但是Oracle10g增加了GROUP BY STOPKEY執行路徑,使得使用者在執行GROUP BY操作時,可以根據STOPKEY隨時中止正在執行的操作。

這使得標準分頁函式對於GROUP BY操作重新發揮了作用。

SQL> CREATE TABLE T AS SELECT ROWNUM ID, A.* FROM DBA_OBJECTS A;

表已建立。

SQL> CREATE INDEX IND_T_CREATED ON T (CREATED);

索引已建立。

SQL> ALTER TABLE T MODIFY CREATED NOT NULL;

表已更改。

SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';

會話已更改。

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

PL/SQL 過程已成功完成。

SQL> SET AUTOT ON
SQL> SET TIMING ON
SQL> SELECT *
2 FROM
3 (
4 SELECT ROWNUM RN, A.*
5 FROM
6 (
7 SELECT CREATED, COUNT(*)
8 FROM T
9 GROUP BY CREATED
10 ) A
11 WHERE ROWNUM < 20
12 )
13 WHERE RN >= 10;

RN CREATED COUNT(*)
---------- ------------------- ----------
10 2005-12-19 17:07:57 50
11 2005-12-19 17:07:58 36
12 2005-12-19 17:08:24 10
13 2005-12-19 17:08:25 49
14 2005-12-19 17:08:26 66
15 2005-12-19 17:08:27 62
16 2005-12-19 17:08:28 81
17 2005-12-19 17:08:29 82
18 2005-12-19 17:08:33 1
19 2005-12-19 17:08:35 3

已選擇10行。

已用時間: 00: 00: 00.04

執行計劃
----------------------------------------------------------
Plan hash value: 3639065582

------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 19 | 665 | 1 (0)|
|* 1 | VIEW | | 19 | 665 | 1 (0)|
|* 2 | COUNT STOPKEY | | | | |
| 3 | VIEW | | 973 | 21406 | 1 (0)|
|* 4 | SORT GROUP BY STOPKEY| | 973 | 7784 | 1 (0)|
| 5 | INDEX FULL SCAN | IND_T_CREATED | 984 | 7872 | 1 (0)|
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter("RN">=10)
2 - filter(ROWNUM<20)
4 - filter(ROWNUM<20)

統計資訊
----------------------------------------------------------
1 recursive calls
0 db block gets
67 consistent gets
0 physical reads
0 redo size
730 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
10 rows processed

SQL> SELECT *
2 FROM
3 (
4 SELECT ROWNUM RN, A.*
5 FROM
6 (
7 SELECT CREATED, COUNT(*)
8 FROM T
9 GROUP BY CREATED
10 ) A
11 )
12 WHERE RN >= 10
13 AND RN < 20;

RN CREATED COUNT(*)
---------- ------------------- ----------
10 2005-12-19 17:09:27 34
11 2005-12-19 17:09:31 29
12 2005-12-19 17:09:40 29
13 2005-12-19 17:09:58 11
14 2005-12-19 17:10:06 6
15 2005-12-19 17:10:12 48
16 2005-12-19 17:10:20 24
17 2005-12-19 17:10:37 8
18 2005-12-19 17:10:40 2
19 2005-12-19 17:10:49 2

已選擇10行。

已用時間: 00: 00: 00.06

執行計劃
----------------------------------------------------------
Plan hash value: 4036621539

------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 973 | 34055 | 14 (36)|
|* 1 | VIEW | | 973 | 34055 | 14 (36)|
| 2 | COUNT | | | | |
| 3 | VIEW | | 973 | 21406 | 14 (36)|
| 4 | HASH GROUP BY | | 973 | 7784 | 14 (36)|
| 5 | INDEX FAST FULL SCAN| IND_T_CREATED | 50359 | 393K| 10 (10)|
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter("RN">=10 AND "RN"<20)

統計資訊
----------------------------------------------------------
1 recursive calls
0 db block gets
73 consistent gets
0 physical reads
0 redo size
724 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed

透過上面的執行計劃可以看到,無論使用標準分頁函式,還是使用其他方式,Oracle採用的都是10g特有的執行計劃GROUP BY STOPKEYHASH GROUP BY,與9iGROUP BY相比較,二者的執行效率都很高,不過利用了標準分頁模式,Oracle可以將STOPKEY推入到查詢最內層,使得Oracle在掃描的開始階段就將結果集限制住。從查詢的邏輯讀和執行時間上也可以看出來,GROUP BY STOPKEY的執行效率更高一些。

從這一點上看,Oracle10g的新功能確實使得查詢效率得到提高。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29067253/viewspace-2141081/,如需轉載,請註明出處,否則將追究法律責任。

相關文章