oracle 对视图使用提示?

jhiyze9q  于 2023-10-16  发布在  Oracle
关注(0)|答案(2)|浏览(120)

我有一个视图,我想像这样查询我的视图,从基表中提示一些索引,我可以这样做吗?
我的意思是:

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

我在table1.col1上有一个名为“index1"的索引。
我有一个
查询**:

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

当我看到这个查询的解释计划时,它告诉我这个查询没有使用“index1”,我想指出它。
所以我希望它是,例如:

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

我可以提示视图吗??(如果我不想在创建此视图时指明)

bihw5rsg

bihw5rsg1#

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

1)创建一个包含10,000个相同行的表,并在该表上创建索引。该索引不是选择性的,因此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>

然而,尽管如此,提示通常是在尝试调优查询时的最后手段--通常更可取的做法是找出优化器丢失了哪些信息,并提供适当的统计信息,以便它可以自己做出正确的选择。这是一个更稳定的解决方案。当您被简化为指定涉及多层别名的提示时,情况就更是如此了--例如,对于接触视图定义的人来说,通过更改表名的别名来中断查询太容易了。

ccgok5k5

ccgok5k52#

我尝试了Justin Cave的(答案在旁边)语法

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

但对我不起作用。下一篇:Worked

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

我试用了 *Oracle数据库11 g企业版11.2.0.1.0 - 64位生产 *

相关问题