Filter的一个测试

xiaoxiao2021-02-28  79

Filter的一个测试: 创建测试表 t1 和t2. create table t1 as select * from dba_objects where rownum<=5000; create table t2 as select * from dba_objects where rownum<=5000; 执行该测试SQL,这里使用了提示来收集真实的执行计划 select /*+ gather_plan_statistics */ count(*) from t1 where exists (select 1 from t2 where t2.owner = t1.owner group by t2.object_type having count(*) >= 10) and t1.object_type = 'TABLE'; set autot off; select /*+ gather_plan_statistics */ count(*) from t1 where exists (select 1 from t2 where t2.owner = t1.owner group by t2.object_type having count(*) >= 10) and t1.object_type = 'TABLE'; COUNT(*) ---------- 519 SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST')); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------- --------------- SQL_ID 49t0m3dv35346, child number 0 ------------------------------------- select /*+ gather_plan_statistics */ count(*) from t1 where exists (select 1 from t2 where t2.owner = t1.owner group by t2.object_type having count(*) >= 10) and t1.object_type = 'TABLE' Plan hash value: 2091197476 ----------------------------------------------------------------------------------------------- -------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem | ----------------------------------------------------------------------------------------------- -------------------- | 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 268 | | | | | 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 268 | | | | |* 2 | FILTER | | 1 | | 519 |00:00:00.01 | 268 | | | | |* 3 | TABLE ACCESS FULL | T1 | 1 | 587 | 522 |00:00:00.01 | 67 | | | | |* 4 | FILTER | | 3 | | 2 |00:00:00.01 | 201 | | | | | 5 | HASH GROUP BY | | 3 | 50 | 8 |00:00:00.01 | 201 | 1301K| 1301K| 1074K (0)| |* 6 | TABLE ACCESS FULL| T2 | 3 | 50 | 3449 |00:00:00.01 | 201 | | | | ----------------------------------------------------------------------------------------------- -------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter( IS NOT NULL) 3 - filter("T1"."OBJECT_TYPE"='TABLE') 4 - filter(COUNT(*)>=10) 6 - filter("T2"."OWNER"=:B1) Note ----- - dynamic sampling used for this statement (level=2) 已选择33行。 ①Starts的意思是执行了几次,首先2这个地方执行了1次,是对t1进行全表扫描,返回了522行记录, 测试如下: SQL> select count(*) from t1 where t1.object_type = 'TABLE'; COUNT(*) ---------- 522 ②看 一下4这个结点,执行了3次, 测试: SQL> select distinct owner from t1 where t1.object_type = 'TABLE'; OWNER ------------------------------ OUTLN SYSTEM SYS 总结: 1.Filter就是外部查询返回多少个唯一值,内部查询就访问多少次。 2.产生Filter的方式: ①exists里有group by xx having xx ②exists里有rownum 或者是start with时会产生filter. 3.filter的执行计划一般是不好的,因为外部返回的数据很大的话,就会导致内部查询扫描很多次。 改写exists: 这样改写的原因是owner是传值,其实也就是相当于对owner分组 select /*+ gather_plan_statistics */ count(*) from t1 where owner in (select owner from t2 group by t2.object_type,owner having count(*) >= 10) and t1.object_type = 'TABLE'; select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST')); PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- SQL_ID c07dgxq09xqga, child number 0 ------------------------------------- select /*+ gather_plan_statistics */ count(*) from t1 where owner in (select owner from t2 group by t2.object_type,owner having count(*) >= 10) and t1.object_type = 'TABLE' Plan hash value: 3015395397 ------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem | ------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 134 | | | | | 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 134 | | | | |* 2 | HASH JOIN SEMI | | 1 | 587 | 519 |00:00:00.01 | 134 | 2293K| 2293K| 561K (0)| | 3 | JOIN FILTER CREATE | :BF0000 | 1 | 587 | 522 |00:00:00.01 | 67 | | | | |* 4 | TABLE ACCESS FULL | T1 | 1 | 587 | 522 |00:00:00.01 | 67 | | | | | 5 | VIEW | VW_NSO_1 | 1 | 5002 | 10 |00:00:00.01 | 67 | | | | |* 6 | FILTER | | 1 | | 10 |00:00:00.01 | 67 | | | | | 7 | HASH GROUP BY | | 1 | 5002 | 21 |00:00:00.01 | 67 | 1214K| 1214K| 1249K (0)| | 8 | JOIN FILTER USE | :BF0000 | 1 | 5002 | 3449 |00:00:00.01 | 67 | | | | |* 9 | TABLE ACCESS FULL| T2 | 1 | 5002 | 3449 |00:00:00.01 | 67 | | | | ------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OWNER"="OWNER") 4 - filter("T1"."OBJECT_TYPE"='TABLE') 6 - filter(COUNT(*)>=10) 9 - filter(SYS_OP_BLOOM_FILTER(:BF0000,"OWNER")) Note ----- - dynamic sampling used for this statement (level=2) 已选择36行。
转载请注明原文地址: https://www.6miu.com/read-85400.html

最新回复(0)