您的位置:首页 > 其它

如何得到正确的执行计划

2015-03-23 22:04 246 查看
如何得到正确的执行计划
00:09:10 scott@orcl> var x number;
00:09:31 scott@orcl> var y number;
00:09:35 scott@orcl> exec :x:=0;

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
00:09:48 scott@orcl> exec :y:=100000;

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
00:09:59 scott@orcl> select count(*) from t1 where object_id between :x and :y;

Elapsed: 00:00:00.07

Execution Plan
----------------------------------------------------------
Plan hash value: 2351893609

-----------------------------------------------------------------------------
| Id  | Operation          | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |        |     1 |     4 |     6   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |        |     1 |     4 |            |          |
|*  2 |   FILTER           |        |       |       |            |          |
|*  3 |    INDEX RANGE SCAN| IDX_T1 |   863 |  3452 |     6   (0)| 00:00:01 |
-----------------------------------------------------------------------------

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

2 - filter(TO_NUMBER(:Y)>=TO_NUMBER(:X))
3 - access("OBJECT_ID">=TO_NUMBER(:X) AND "OBJECT_ID"<=TO_NUMBER(:Y))

Statistics
----------------------------------------------------------
1  recursive calls
0  db block gets
775  consistent gets
0  physical reads
0  redo size
528  bytes sent via SQL*Net to client
520  bytes received via SQL*Net from client
2  SQL*Net roundtrips to/from client
0  sorts (memory)
0  sorts (disk)
1  rows processed

那么这个执行计划是不是正确的呢,我们实际执行下这条sql语句

select * from table(dbms_xplan.display_cursor('56vqgzn8rn5hh',null,'advanced'));
01:10:04 sys@orcl> select * from table(dbms_xplan.display_cursor('9dhu3xk2zu531',null,'advanced'));

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------
SQL_ID  9dhu3xk2zu531, child number 0
-------------------------------------
select count(*) from t1 where object_id between :x and :y

Plan hash value: 1410530761

---------------------------------------------------------------------------------
| Id  | Operation              | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |        |       |       |   211 (100)|          |
|   1 |  SORT AGGREGATE        |        |     1 |     4 |            |          |
|*  2 |   FILTER               |        |       |       |            |          |
|*  3 |    INDEX FAST FULL SCAN| IDX_T1 |   345K|  1348K|   211   (1)| 00:00:03 |
---------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

1 - SEL$1
3 - SEL$1 / T1@SEL$1

Outline Data
-------------

/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
DB_VERSION('11.2.0.4')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX_FFS(@"SEL$1" "T1"@"SEL$1" ("T1"."OBJECT_ID"))
END_OUTLINE_DATA
*/

Peeked Binds (identified by position):
--------------------------------------

1 - :X (NUMBER): 0
2 - :Y (NUMBER): 100000

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

2 - filter(:Y>=:X)
3 - filter(("OBJECT_ID">=:X AND "OBJECT_ID"<=:Y))

Column Projection Information (identified by operation id):
-----------------------------------------------------------

1 - (#keys=0) COUNT(*)[22]

52 rows selected.

我们可以看到,实际上走的是INDEX FAST FULL SCAN,由此可见,set autotract on并不是实际的执行计划,特别是参数是绑定变量的时候,并不一定能呈现正确的执行计划
我们需要用
select * from table(dbms_xplan.display_cursor('9dhu3xk2zu531',null,'advanced'));
根据sql_id来查看正确的执行计划
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: