您的位置:首页 > 其它

FILTER的执行次数和驱动表问题

2014-05-08 13:35 267 查看
drop table test1;
create table test1 as select * from dba_objects where rownum<1000;

drop table test2;
create table test2 as select * from dba_objects where rownum<1000;

insert into test1 select * from test1;

update test2 set owner='SCOTT';

BEGIN
DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SCOTT',
tabname          => 'TEST1',
estimate_percent => 100,
method_opt       => 'for  columns owner size 200',
no_invalidate    => FALSE,
degree           => 1,
cascade          => TRUE);
END;
/

BEGIN
DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'SCOTT',
tabname          => 'TEST2',
estimate_percent => 100,
method_opt       => 'for  columns owner size 200',
no_invalidate    => FALSE,
degree           => 1,
cascade          => TRUE);
END;
/

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

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

--------------------------------------------
SQL_ID	a23r1uchdaafg, child number 0
-------------------------------------
An uncaught error happened in prepare_sql_statement : ORA-01403: no data found

Plan hash value: 1896454807

--------------------------------------------------------------------------------------
| Id  | Operation	   | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |	   |	  1 |	     |	 1998 |00:00:00.07 |   13763 |
|*  1 |  FILTER 	   |	   |	  1 |	     |	 1998 |00:00:00.07 |   13763 |
|   2 |   TABLE ACCESS FULL| TEST1 |	  1 |	 999 |	 1998 |00:00:00.01 |	 163 |
|*  3 |   TABLE ACCESS FULL| TEST2 |   1346 |	   1 |	 1346 |00:00:00.06 |   13600 |
--------------------------------------------------------------------------------------

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

1 - filter(("OWNER"='SCOTT' OR  IS NOT NULL))
3 - filter(("OWNER"='SCOTT' AND "OBJECT_ID"=:B1))

21 rows selected.

查看FILTER的执行次数,此时 被驱动表TEST2执行了1346次,那这个1346次是怎么计算的呢?

SQL> select count(*) from test1;

COUNT(*)
----------
1998

SQL> select count(distinct object_id) from test1;

COUNT(DISTINCTOBJECT_ID)
------------------------
999

网上有人说是count(distinct join列),看来结果不对,有待研究

FILTER能改变驱动表?
SQL> select /*+ leading(test2)*/ * from test1 where owner='SCOTT' or object_id in(select object_id from test2 where owner='SCOTT')
2  ;

1998 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 1896454807

----------------------------------------------------------------------------
| Id  | Operation	   | Name  | Rows  | Bytes | Cost (%CPU)| Time	   |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |	   |	52 |  4420 |	 5   (0)| 00:00:01 |
|*  1 |  FILTER 	   |	   |	   |	   |		|	   |
|   2 |   TABLE ACCESS FULL| TEST1 |   999 | 84915 |	 5   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| TEST2 |	 1 |	18 |	 5   (0)| 00:00:01 |
----------------------------------------------------------------------------

FILTER无法改变驱动表

1. 减少扫描 次数

2. 无法减少扫描次数,减少扫描体积
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: