您的位置:首页 > 其它

TABLE ACCESS BY INDEX ROWID前面的星号

2014-07-02 20:54 351 查看
<pre name="code" class="sql">SQL> create table  test as select * from dba_objects;

Table created.

select * from test where object_id=10 and OWNER='SYS';

SQL> select count(*) from test where object_id=10;

COUNT(*)
----------
1

SQL> select count(*) from test;

COUNT(*)
----------
74443

模拟插入object_id=10 and OWNER='SYS'的记录

SQL> select object_id,owner,count(*) from test2 group by object_id,owner having object_id=10;

OBJECT_ID OWNER                            COUNT(*)
---------- ------------------------------ ----------
10 TEST                                72636
10 SYS                                 10003

SQL> select count(*) from test2;

COUNT(*)
----------
1578831

SQL> create index test2_idx1 on test2(object_id);

索引已创建。

分析下表:
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'TEST',
tabname          => 'TEST2',
estimate_percent => 30,
method_opt       => 'for all columns size repeat',
no_invalidate    => FALSE,
degree           => 8,
cascade          => TRUE);
END;

SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------

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

-----------------------
SQL_ID  gmv066f6cfyhd, child number 0
-------------------------------------
select * from test2 where object_id=10 and owner='SYS'

Plan hash value: 3497718064

-------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |            |      1 |        |  10003 |00:00:00.60 |    2628 |   1297 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| TEST2      |      1 |      1 |  10003 |00:00:00.60 |    2628 |   1297 |
|*  2 |   INDEX RANGE SCAN          | TEST2_IDX1 |      1 |     22 |  82639 |00:00:00.15 |     830 |    163 |
-------------------------------------------------------------------------------------------------------------

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

1 - filter("OWNER"='SYS')
2 - access("OBJECT_ID"=10)

已选择20行。

可以看到object_id=10的记录数为82639行,回表后过滤OWNER='SYS'后为10003行,此时有10003个rowid需要回表

逻辑读为:

SQL> select * from test2 where object_id=10 and owner='SYS'
2  ;

已选择10003行。

执行计划
----------------------------------------------------------
Plan hash value: 3497718064

------------------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |            |     1 |    96 |    24   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| TEST2      |     1 |    96 |    24   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | TEST2_IDX1 |    22 |       |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------------

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

1 - filter("OWNER"='SYS')
2 - access("OBJECT_ID"=10)

统计信息
----------------------------------------------------------
1  recursive calls
0  db block gets
2628  consistent gets
0  physical reads
0  redo size
393766  bytes sent via SQL*Net to client
7741  bytes received via SQL*Net from client
668  SQL*Net roundtrips to/from client
0  sorts (memory)
0  sorts (disk)
10003  rows processed

创建组合索引后:
SQL> create index test2_idx2 on test2(object_id,owner);

SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------

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

-----------------------
SQL_ID  gmv066f6cfyhd, child number 0
-------------------------------------
select * from test2 where object_id=10 and owner='SYS'

Plan hash value: 3385680830

-------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |            |      1 |        |  10003 |00:00:00.08 |    1488 |     27 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TEST2      |      1 |      1 |  10003 |00:00:00.08 |    1488 |     27 |
|*  2 |   INDEX RANGE SCAN          | TEST2_IDX2 |      1 |     22 |  10003 |00:00:00.02 |     693 |     27 |
-------------------------------------------------------------------------------------------------------------

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

2 - access("OBJECT_ID"=10 AND "OWNER"='SYS')

此时直接索引过滤后顺下10003行记录,不需要回表在过滤数据。

结论:看到TABLE ACCESS BY INDEX ROWID前面有*,说明索引扫描返回rowid后,还要在表上进行过滤,比如上面索引扫描后返回了82639

个rowid,在表上过滤后只顺下10003个,这样就可以通过创建组合索引来减少回表的rowid.



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐