SCOTT@test01p> @ver
BANNER CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 0
SCOTT@test01p> select rowid ,t.* from t where id between 1 and 3;
ROWID ID NAME
------------------ ---------- --------------------
AAAWxnAAJAAAAC1AAA 1 aaaaaaaaaaaaaaaaaaaa
AAAWxnAAJAAAAC3AAA 2 bbbbbbbbbbbbbbbbbbbb
AAAWxnAAJAAAAC3AAB 3 cccccccccccccccccccc
COTT@test01p> @lookup_rowid AAAWxnAAJAAAAC1AAA
OBJECT FILE BLOCK ROW DBA
--------- ---------- ---------- ---------- --------------------
93287 9 181 0 9,181
COTT@test01p> @lookup_rowid AAAWxnAAJAAAAC3AAA
OBJECT FILE BLOCK ROW DBA
--------- ---------- ---------- ---------- --------------------
93287 9 183 0 9,183
SCOTT@test01p> select * from t where id=42;
ID NAME
---------- --------------------
42 xxxxxxxxxxxxxxxxxxxx
SCOTT@test01p> @dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID dvv86knmasnpw, child number 0
-------------------------------------
select * from t where id=42
Plan hash value: 1149237570
--------------------------------------------------------------------
| Id | Operation | Name | E-Rows | Cost (%CPU)|
--------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 1 (100)|
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 1 (0)|
|* 2 | INDEX UNIQUE SCAN | I_T_ID | 1 | 0 (0)|
--------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=42)SCOTT@test01p> select * from t where id between 1 and 3 ;
ID NAME
---------- --------------------
1 aaaaaaaaaaaaaaaaaaaa
2 bbbbbbbbbbbbbbbbbbbb
3 cccccccccccccccccccc
SCOTT@test01p> @dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID 38raj6puvxubp, child number 0
-------------------------------------
select * from t where id between 1 and 3
Plan hash value: 3446268138
----------------------------------------------------------------------------
| Id | Operation | Name | E-Rows | Cost (%CPU)|
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 2 (100)|
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T | 3 | 2 (0)|
|* 2 | INDEX RANGE SCAN | I_T_ID | 3 | 1 (0)|
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID">=1 AND "ID"<=3)--执行计划使用TABLE ACCESS BY INDEX ROWID BATCHED。 对比以上看看两者的差别到底在那里呢?视乎做范围扫描时,会出现BATCHED。set autot traceonly
select * from t where id=42;
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2 consistent gets
0 physical reads
0 redo size
483 bytes sent via SQL*Net to client
533 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed--consistent gets=2,如果存在recursive calls,可以执行多次消除影响。
set autot traceonly
select * from t where id between 1 and 3 ;
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
735 bytes sent via SQL*Net to client
544 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
3 rows processed
SCOTT@test01p> show array
arraysize 200
SCOTT@test01p> Select * from t where id between 4 and 100 ;
ID NAME
---------- --------------------
4 xxxxxxxxxxxxxxxxxxxx
....
100 xxxxxxxxxxxxxxxxxxxx
97 rows selected.
SCOTT@test01p> @dpc '' ' '
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID 0z6wka791vxz2, child number 0
-------------------------------------
Select * from t where id between 4 and 100
Plan hash value: 3446268138
----------------------------------------------------------------------------
| Id | Operation | Name | E-Rows | Cost (%CPU)|
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 3 (100)|
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T | 98 | 3 (0)|
|* 2 | INDEX RANGE SCAN | I_T_ID | 98 | 1 (0)|
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID">=4 AND "ID"<=100)
--注意我没有使用hint,执行计划扫描大部分数据,因为id between 4 and 100的一个数据块中。
SCOTT@test01p> select distinct DBMS_ROWID.ROWID_BLOCK_NUMBER(rowid) from t where id between 4 and 100;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------
183--按照以前执行计划正常应该选择全表扫描,而现在执行计划选择的是INDEX RANGE SCAN。
SCOTT@test01p> set autot traceonly
SCOTT@test01p> Select * from t where id between 4 and 100 ;
97 rows selected.
Execution Plan
---------------------------
Plan hash value: 3446268138
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 98 | 2352 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T | 98 | 2352 | 3 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | I_T_ID | 98 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID">=4 AND "ID"<=100)Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
3461 bytes sent via SQL*Net to client
544 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
97 rows processed
--可以发现consistent gets=4,这个4如何得到的呢?
SCOTT@test01p> Select * from t where id between 1 and 100 ;
100 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3446268138
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 2400 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T | 100 | 2400 | 3 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | I_T_ID | 100 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID">=1 AND "ID"<=100)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
3548 bytes sent via SQL*Net to client
544 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
100 rows processed--执行计划扫描全部数据,选择的还是索引扫描,consistent gets=4,注意这个是颠覆性的,如果数据的聚集因子很小,
SCOTT@test01p> select object_id,data_object_id,object_name from dba_objects where object_name in('I_T_ID','T') and wner=user;OBJECT_ID DATA_OBJECT_ID OBJECT_NAME
---------- -------------- ------------
93287 93287 T
93288 93288 I_T_ID
SCOTT@test01p> select segment_name,segment_type,header_file,header_block,bytes,blocks from dba_segments where segment_name in('I_T_ID','T') and wner=user;
SEGMENT_NAME SEGMENT_TYPE HEADER_FILE HEADER_BLOCK BYTES BLOCKS
-------------------- ------------------ ----------- ------------ ---------- ----------
I_T_ID INDEX 9 186 65536 8
T TABLE 9 178 65536 8
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-772371/ ,如需转载,请注明出处,否则将追究法律责任。