代码之家  ›  专栏  ›  技术社区  ›  kupa

对视图使用提示?

  •  11
  • kupa  · 技术社区  · 15 年前

    我有一个视图,我想这样查询我的视图以提示来自基表的一些索引,可以这样做吗?

    我是说:

    --view
    create or replace view temp_view
    as select col1,col2,col3
    from table1,table2....
    

    我有一个 指数 在 表1.col1 打电话来” 索引1 ".

    我有一个 查询 :

    --query
    select * 
    from temp_view 
    where col1=12;
    

    当我看到这个查询的explain plan时,它告诉我这个查询不使用“index1”,我想指出它。。

    所以我希望它是,例如:

    --query with hint
    select /*+ index(temp_view  index1)*/* 
    from temp_view 
    where col1=12;
    

    我能给你一些意见提示吗??(如果我不想在创建此视图时指出它)

    2 回复  |  直到 12 年前
        1
  •  16
  •   Justin Cave    15 年前

    您可以对视图使用查询提示来强制Oracle在基表上使用索引。但您需要知道基础视图中基表(如果有的话)的别名。一般语法是 /*+ index(<<alias of view from query>> <<alias of table from view>> <<index name>>) */

    一个例子

    1)创建具有10000行相同行的表,并在该表上创建索引。索引没有选择性,所以Oracle不想使用它

    SQL> ed
    Wrote file afiedt.buf
    
      1  create table foo
      2  as
      3  select 1 col1
      4    from dual
      5* connect by level <= 10000
    SQL> /
    
    Table created.
    
    SQL> create index idx_foo on foo(col1);
    
    Index created.
    

    2)确认索引未正常使用,但Oracle将在使用时提供提示

    SQL> set autotrace traceonly;
    SQL> select * from foo where col1 = 1;
    
    10000 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1245013993
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      | 10000 |   126K|     7   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| FOO  | 10000 |   126K|     7   (0)| 00:00:01 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("COL1"=1)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    
    Statistics
    ----------------------------------------------------------
              9  recursive calls
              0  db block gets
            713  consistent gets
              5  physical reads
              0  redo size
         172444  bytes sent via SQL*Net to client
           7849  bytes received via SQL*Net from client
            668  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
          10000  rows processed
    
    SQL> select /*+ index(foo idx_foo) */ *
      2    from foo
      3   where col1 = 1;
    
    10000 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 15880034
    
    ----------------------------------------------------------------------------
    | Id  | Operation        | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT |         | 10000 |   126K|    25   (0)| 00:00:01 |
    |*  1 |  INDEX RANGE SCAN| IDX_FOO | 10000 |   126K|    25   (0)| 00:00:01 |
    ----------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - access("COL1"=1)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    
    Statistics
    ----------------------------------------------------------
              7  recursive calls
              0  db block gets
            715  consistent gets
             15  physical reads
              0  redo size
         172444  bytes sent via SQL*Net to client
           7849  bytes received via SQL*Net from client
            668  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
          10000  rows processed
    

    3)现在创建视图。通过指定查询中的视图别名和视图定义中的表别名,验证针对视图的常规查询不使用索引,而是强制使用索引

    SQL> create view vw_foo
      2  as
      3  select col1
      4    from foo f;
    
    View created.
    
    SQL> select col1
      2    from vw_foo
      3   where col1 = 1;
    
    10000 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1245013993
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      | 10000 |   126K|     7   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| FOO  | 10000 |   126K|     7   (0)| 00:00:01 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("COL1"=1)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    
    Statistics
    ----------------------------------------------------------
             16  recursive calls
              0  db block gets
            715  consistent gets
              0  physical reads
              0  redo size
         172444  bytes sent via SQL*Net to client
           7849  bytes received via SQL*Net from client
            668  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
          10000  rows processed
    
    SQL> select /*+ index(vf f idx_foo) */ col1
      2    from vw_foo vf
      3   where col1 = 1;
    
    10000 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 15880034
    
    ----------------------------------------------------------------------------
    | Id  | Operation        | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT |         | 10000 |   126K|    25   (0)| 00:00:01 |
    |*  1 |  INDEX RANGE SCAN| IDX_FOO | 10000 |   126K|    25   (0)| 00:00:01 |
    ----------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - access("COL1"=1)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    
    Statistics
    ----------------------------------------------------------
             14  recursive calls
              0  db block gets
            717  consistent gets
              0  physical reads
              0  redo size
         172444  bytes sent via SQL*Net to client
           7849  bytes received via SQL*Net from client
            668  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
          10000  rows processed
    
    SQL>
    

    尽管如此,在试图优化查询时,提示通常是最后的手段——通常最好找出优化器缺少的信息并提供适当的统计数据,以便它能够自己做出正确的选择。这是一个更稳定的解决方案。双重原因是,当您被简化为指定涉及多个别名层的提示时——例如,对于触摸视图定义的人来说,通过更改表名的别名来中断查询太容易了。

        2
  •  1
  •   3per    8 年前

    我试过贾斯汀·卡夫的语法(旁边的答案)

    select /*+ index(vf f idx_foo) */ col1
    from vw_foo vf
    where col1 = 1;
    

    ,但这对我不起作用。下一个是工作

    select /*+ index(vf.f idx_foo) */ col1
    from vw_foo vf
    where col1 = 1;
    

    我试过了 Oracle Database 11g企业版11.2.0.1.0版-64位生产