此脚本不依赖统计信息。

    嵌套循环的被驱动表应该走索引,以下脚本抓出嵌套循环被驱动表走了全表扫描的 SQL,同时根据表大小降序显示。

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

    我们在 Scott 账户中运行如下 SQL,强制两表走嵌套循环,强制两表走全表扫描。

    1. select /*+ use_nl(a,b) full(a) full(b) */ *
    2. from a, b
    3. where a.object_id = b.object_id;

    我们通过以上脚本将其抓出。

    1. select c.sql_text, a.sql_id, b.object_name, d.mb
    2. from v$sql_plan a,
    3. (select *
    4. from (select sql_id,
    5. child_number,
    6. object_owner,
    7. object_name,
    8. parent_id,
    9. operation,
    10. options,
    11. row_number() over(partition by sql_id, child_number, parent_id order by id) rn
    12. from v$sql_plan)
    13. where rn = 2) b,
    14. v$sql c,
    15. (select owner, segment_name, sum(bytes / 1024 / 1024) mb
    16. from dba_segments
    17. group by owner, segment_name) d
    18. where b.sql_id = c.sql_id
    19. and b.child_number = c.child_number
    20. and b.object_owner = 'SCOTT'
    21. and a.sql_id = b.sql_id
    22. and a.child_number = b.child_number
    23. and a.operation like '%NESTED LOOPS%'
    24. and a.id = b.parent_id
    25. and b.operation = 'TABLE ACCESS'
    26. and b.options = 'FULL'
    27. and b.object_owner = d.owner
    28. and b.object_name = d.segment_name
    29. order by 4 desc;
    1. SQL_TEXT SQL_ID OBJECT_NAME MB
    2. --------------------------------------------- --------------- ------------ ----------
    3. select /*+ use_nl(a,b) full(a) full(b) */ * 6prgcr0qcj3qr B 9
    4. from a, b where a.object_id = b.object_id