此脚本不依赖统计信息。

    我们在第 5 章中提到过笛卡儿积连接。当两表没有关联条件的时候就会走笛卡儿积,当 Rows 被估算为 1 的时候,也可能走笛卡儿积连接。下面脚本抓出走了笛卡儿积的 SQL。

    1. select c.sql_text,
    2. a.sql_id,
    3. b.object_name,
    4. a.filter_predicates filter,
    5. a.access_predicates predicate,
    6. d.mb
    7. from v$sql_plan a,
    8. (select *
    9. from (select sql_id,
    10. child_number,
    11. object_owner,
    12. object_name,
    13. parent_id,
    14. operation,
    15. options,
    16. row_number() over(partition by sql_id, child_number, parent_id order by id) rn
    17. from v$sql_plan)
    18. where rn = 1) b,
    19. v$sql c,
    20. (select owner, segment_name, sum(bytes / 1024 / 1024) mb
    21. from dba_segments
    22. group by owner, segment_name) d
    23. where b.sql_id = c.sql_id
    24. and b.child_number = c.child_number
    25. and b.object_owner = 'SCOTT'
    26. and a.sql_id = b.sql_id
    27. and a.child_number = b.child_number
    28. and a.operation = 'MERGE JOIN'
    29. and a.id = b.parent_id
    30. and a.options = 'CARTESIAN'
    31. and b.object_owner = d.owner
    32. and b.object_name = d.segment_name
    33. order by 4 desc;

    在 Scott 账户中运行如下 SQL。

    1. select * from a,b;

    利用脚本将其抓出。

    1. select c.sql_text,
    2. a.sql_id,
    3. b.object_name,
    4. a.filter_predicates filter,
    5. a.access_predicates predicate,
    6. d.mb
    7. from v$sql_plan a,
    8. (select *
    9. from (select sql_id,
    10. child_number,
    11. object_owner,
    12. object_name,
    13. parent_id,
    14. operation,
    15. options,
    16. row_number() over(partition by sql_id, child_number, parent_id order by id) rn
    17. from v$sql_plan)
    18. where rn = 1) b,
    19. v$sql c,
    20. (select owner, segment_name, sum(bytes / 1024 / 1024) mb
    21. from dba_segments
    22. group by owner, segment_name) d
    23. where b.sql_id = c.sql_id
    24. and b.child_number = c.child_number
    25. and b.object_owner = 'SCOTT'
    26. and a.sql_id = b.sql_id
    27. and a.child_number = b.child_number
    28. and a.operation = 'MERGE JOIN'
    29. and a.id = b.parent_id
    30. and a.options = 'CARTESIAN'
    31. and b.object_owner = d.owner
    32. and b.object_name = d.segment_name
    33. order by 4 desc;
    1. SQL_TEXT SQL_ID OBJECT_NAME FILTER PREDICATE MB
    2. -------------------- --------------- ------------ ---------- ---------- ----------
    3. select * from a,b 9kwdjbbs50kcu A 9