技术开发 频道

Oracle分页查询语句(三)

【IT168 技术文档】
 
继续看查询的第二种情况,包含表连接的情况:
SQL> CREATE TABLE T AS SELECT * FROM DBA_USERS; 表已创建。 SQL> CREATE TABLE T1 AS SELECT * FROM DBA_SOURCE; 表已创建。 SQL> ALTER TABLE T ADD CONSTRAINT PK_T PRIMARY KEY (USERNAME); 表已更改。 SQL> ALTER TABLE T1 ADD CONSTRAINT FK_T1_OWNER FOREIGN KEY (OWNER) 2 REFERENCES T(USERNAME); 表已更改。 SQL> CREATE INDEX IND_T1_OWNER ON T1(NAME); 索引已创建。 SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T') PL/SQL 过程已成功完成。 SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T1') PL/SQL 过程已成功完成。
    创建了T表和T1表,默认情况下,HASH JOIN的效率要比NESTED LOOP高很多:
SQL> SET AUTOT TRACE SQL> SELECT * FROM T, T1 WHERE T.USERNAME = T1.OWNER; 已选择96985行。 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=844 Card=96985 Bytes=46164860) 1 0 HASH JOIN (Cost=844 Card=96985 Bytes=46164860) 2 1 TABLE ACCESS (FULL) OF 'T' (Cost=2 Card=12 Bytes=1044) 3 1 TABLE ACCESS (FULL) OF 'T1' (Cost=826 Card=96985 Bytes=37727165) Statistics ---------------------------------------------------------- 39 recursive calls 0 db block gets 14475 consistent gets 7279 physical reads 0 redo size 37565579 bytes sent via SQL*Net to client 71618 bytes received via SQL*Net from client 6467 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 96985 rows processed SQL> SELECT /*+ FIRST_ROWS */ * FROM T, T1 WHERE T.USERNAME = T1.OWNER; 已选择96985行。 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=97811 Card=96985 Bytes=46164860) 1 0 NESTED LOOPS (Cost=97811 Card=96985 Bytes=46164860) 2 1 TABLE ACCESS (FULL) OF 'T1' (Cost=826 Card=96985 Bytes=37727165) 3 1 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=1 Card=1 Bytes=87) 4 3 INDEX (UNIQUE SCAN) OF 'PK_T' (UNIQUE) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 117917 consistent gets 7268 physical reads 0 redo size 37565579 bytes sent via SQL*Net to client 71618 bytes received via SQL*Net from client 6467 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 96985 rows processed
但是如果分页查询的内层是这种连接查询的话,使用NESTED LOOP可以更快的得到前N条记录。

下面看一下这种情况下的分页查询情况:
SQL> SELECT USER_ID, USERNAME, NAME 2 FROM 3 ( 4 SELECT ROWNUM RN, USER_ID, USERNAME, NAME 5 FROM 6 ( 7 SELECT T.USER_ID, T.USERNAME, T1.NAME 8 FROM T, T1 9 WHERE T.USERNAME = T1.OWNER 10 ) 11 WHERE ROWNUM <= 20 12 ) 13 WHERE RN >= 11; 已选择10行。 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=830 Card=20 Bytes=1200) 1 0 VIEW (Cost=830 Card=20 Bytes=1200) 2 1 COUNT (STOPKEY) 3 2 HASH JOIN (Cost=830 Card=96985 Bytes=2909550) 4 3 TABLE ACCESS (FULL) OF 'T' (Cost=2 Card=12 Bytes=132) 5 3 TABLE ACCESS (FULL) OF 'T1' (Cost=826 Card=96985 Bytes=1842715) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 8 consistent gets 7 physical reads 0 redo size 574 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 /*+ FIRST_ROWS */ USER_ID, USERNAME, NAME 2 FROM 3 ( 4 SELECT ROWNUM RN, USER_ID, USERNAME, NAME 5 FROM 6 ( 7 SELECT T.USER_ID, T.USERNAME, T1.NAME 8 FROM T, T1 9 WHERE T.USERNAME = T1.OWNER 10 ) 11 WHERE ROWNUM <= 20 12 ) 13 WHERE RN >= 11; 已选择10行。 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=97811 Card=20 Bytes=1200) 1 0 VIEW (Cost=97811 Card=20 Bytes=1200) 2 1 COUNT (STOPKEY) 3 2 NESTED LOOPS (Cost=97811 Card=96985 Bytes=2909550) 4 3 TABLE ACCESS (FULL) OF 'T1' (Cost=826 Card=96985 Bytes=1842715) 5 3 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=1 Card=1 Bytes=11) 6 5 INDEX (UNIQUE SCAN) OF 'PK_T' (UNIQUE) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 28 consistent gets 0 physical reads 0 redo size 574 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
看上去似乎HASH JOIN效率更高,难道上面说错了。
0
相关文章