已归录

假设 hr.cyt 表是 dba_tables 的复制,在 cyt.table_name 列上有索引。

下面的查询会走索引:

SQL> explain plan for select owner from cyt where table_name= :a; 
SQL> select * from table(dbms_xplan.display(null,null,'outline'));


从输出结果可以知道,走的索引,输出结果中的 Outline Data 区域的数据如下:

......
Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      INDEX_RS_ASC(@"SEL$1" "CYT"@"SEL$1" ("CYT"."TABLE_NAME"))
      OUTLINE_LEAF(@"SEL$1")
      ALL_ROWS
      DB_VERSION('11.2.0.4')
      OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
      IGNORE_OPTIM_EMBEDDED_HINTS
      END_OUTLINE_DATA
  */
......

下面的查询走的全表扫描:

SQL> explain plan for select /*+full(CYT)*/ owner from cyt where table_name= :a;    
SQL> select * from table(dbms_xplan.display(null,null,'outline'));

从输出结果可以知道,走的全表扫描,输出结果中的 Outline Data 区域的数据如下:

......
Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      FULL(@"SEL$1" "CYT"@"SEL$1")    <-- 注意这儿的内容,后面会用
      OUTLINE_LEAF(@"SEL$1")
      ALL_ROWS
      DB_VERSION('11.2.0.4')
      OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
      IGNORE_OPTIM_EMBEDDED_HINTS
      END_OUTLINE_DATA
  */
......

使用 SQL Profile 固定执行计划,将 SQL 语句跟全表扫描固定起来:

SQL> declare
     v_hints sys.sqlprof_attr;
     begin
         v_hints := sys.sqlprof_attr('FULL(@"SEL$1" "CYT"@"SEL$1")');  -- 来自上面的 Outline Data
         dbms_sqltune.import_sql_profile(
         'select owner from cyt where table_name= :a',   -- 要固定执行计划的 SQL 语句
         v_hints,
         'cy_profile_name',   -- Profile 的名字
         force_match => true);
     end;
/

固定了执行计划后,即使没有 hint,也走的全表扫描:

SQL> explain plan for select owner from cyt where table_name= :a;
SQL> select * from table(dbms_xplan.display);
-- By 许望(RHCA、OCM、VCP)
最后修改:2020 年 05 月 22 日 01 : 13 PM
如果觉得我的文章对你有用,请随意赞赏