此脚本不依赖统计信息。
我们在第 5 章中提到过笛卡儿积连接。当两表没有关联条件的时候就会走笛卡儿积,当 Rows 被估算为 1 的时候,也可能走笛卡儿积连接。下面脚本抓出走了笛卡儿积的 SQL。
select c.sql_text,a.sql_id,b.object_name,a.filter_predicates filter,a.access_predicates predicate,d.mbfrom v$sql_plan a,(select *from (select sql_id,child_number,object_owner,object_name,parent_id,operation,options,row_number() over(partition by sql_id, child_number, parent_id order by id) rnfrom v$sql_plan)where rn = 1) b,v$sql c,(select owner, segment_name, sum(bytes / 1024 / 1024) mbfrom dba_segmentsgroup by owner, segment_name) dwhere b.sql_id = c.sql_idand b.child_number = c.child_numberand b.object_owner = 'SCOTT'and a.sql_id = b.sql_idand a.child_number = b.child_numberand a.operation = 'MERGE JOIN'and a.id = b.parent_idand a.options = 'CARTESIAN'and b.object_owner = d.ownerand b.object_name = d.segment_nameorder by 4 desc;
在 Scott 账户中运行如下 SQL。
select * from a,b;
利用脚本将其抓出。
select c.sql_text,a.sql_id,b.object_name,a.filter_predicates filter,a.access_predicates predicate,d.mbfrom v$sql_plan a,(select *from (select sql_id,child_number,object_owner,object_name,parent_id,operation,options,row_number() over(partition by sql_id, child_number, parent_id order by id) rnfrom v$sql_plan)where rn = 1) b,v$sql c,(select owner, segment_name, sum(bytes / 1024 / 1024) mbfrom dba_segmentsgroup by owner, segment_name) dwhere b.sql_id = c.sql_idand b.child_number = c.child_numberand b.object_owner = 'SCOTT'and a.sql_id = b.sql_idand a.child_number = b.child_numberand a.operation = 'MERGE JOIN'and a.id = b.parent_idand a.options = 'CARTESIAN'and b.object_owner = d.ownerand b.object_name = d.segment_nameorder by 4 desc;
SQL_TEXT SQL_ID OBJECT_NAME FILTER PREDICATE MB-------------------- --------------- ------------ ---------- ---------- ----------select * from a,b 9kwdjbbs50kcu A 9
