此脚本不依赖统计信息。

    我们在第 4 章中提到,INDEX FULL SCAN 会扫描索引中所有的叶子块,单块读。如果索引很大,执行计划中出现了 INDEX FULL SCAN,这时 SQL 会出现严重的性能问题,因此我们需要抓出走了 INDEX FULL SCAN 的 SQL。以下脚本抓出走了 INDEX FULL SCAN 的 SQL 并且根据索引段大小降序显示。

    1. select c.sql_text, c.sql_id, b.object_name, d.mb
    2. from v$sql_plan b,
    3. v$sql c,
    4. (select owner, segment_name, sum(bytes / 1024 / 1024) mb
    5. from dba_segments
    6. group by owner, segment_name) d
    7. where b.sql_id = c.sql_id
    8. and b.child_number = c.child_number
    9. and b.object_owner = 'SCOTT'
    10. and b.operation = 'INDEX'
    11. and b.options = 'FULL SCAN'
    12. and b.object_owner = d.owner
    13. and b.object_name = d.segment_name
    14. order by 4 desc;

    我们在 Scott 账户中运行如下 SQL。

    1. select * from t where object_id is not null order by object_id;

    在 object_id 列创建索引之后,执行上面 SQL 会自动走 INDEX FULL SCAN,使用脚本将其抓出。

    1. select c.sql_text, c.sql_id, b.object_name, d.mb
    2. from v$sql_plan b,
    3. v$sql c,
    4. (select owner, segment_name, sum(bytes / 1024 / 1024) mb
    5. from dba_segments
    6. group by owner, segment_name) d
    7. where b.sql_id = c.sql_id
    8. and b.child_number = c.child_number
    9. and b.object_owner = 'SCOTT'
    10. and b.operation = 'INDEX'
    11. and b.options = 'FULL SCAN'
    12. and b.object_owner = d.owner
    13. and b.object_name = d.segment_name
    14. order by 4 desc;
    1. SQL_TEXT SQL_ID OBJECT_NAME MB
    2. -------------------------------- --------------- --------------- ----------
    3. select * from t where object_id fkan9h6frsn90 IDX_ID 2
    4. is not null order by object_id

    在实际工作中,我们可以对脚本作适当修改,例如过滤出大于 10GB 的索引。