在Oracle(10g)中,当我使用View(非物化视图)时,Oracle在执行视图时会考虑where子句吗?
让我说我有:
MY_VIEW =
SELECT *
FROM PERSON P, ORDERS O
WHERE P.P_ID = O.P_ID
然后我执行以下操作:
SELECT *
FROM MY_VIEW
WHERE MY_VIEW.P_ID = '1234'
执行此操作时,oracle是否首先执行视图查询,然后根据我的where子句(其中MY_VIEW.P_ID ='1234')对其进行过滤,还是作为执行视图的一部分进行过滤?如果它不执行后者,并且P_ID有一个索引,那么我是否也会失去索引功能,因为Oracle会对没有索引的视图而不是具有索引的基表执行查询?
答案 0 :(得分:6)
它不会先执行查询。如果您在P_ID
上有索引,则会使用该索引。
执行计划与将view-code和WHERE
- 子句合并到单个select语句中相同。
您可以自己尝试一下:
EXPLAIN PLAN FOR
SELECT *
FROM MY_VIEW
WHERE MY_VIEW.P_ID = '1234'
接着是
SELECT * FROM TABLE( dbms_xplan.display );
---------------------------------------------------------------------------------
|Id | Operation | Name |Rows| Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 52 | 2 (0)| 00:00:01|
| 1 | NESTED LOOPS | | 1 | 52 | 2 (0)| 00:00:01|
| 2 | TABLE ACCESS BY INDEX ROWID| PERSON | 1 | 26 | 2 (0)| 00:00:01|
| 3 | INDEX UNIQUE SCAN | PK_P | 1 | | 1 (0)| 00:00:01|
| 4 | TABLE ACCESS BY INDEX ROWID| ORDERS | 1 | 26 | 0 (0)| 00:00:01|
| 5 | INDEX RANGE SCAN | IDX_O | 1 | | 0 (0)| 00:00:01|
---------------------------------------------------------------------------------
答案 1 :(得分:0)
WOW !!这很有意思。我有两个不同的解释计划取决于不同的数据量和在逻辑视图内查询(这是我的假设)
`
| 0 | SELECT STATEMENT | | 2 | 132 | 2 (0)|
00:00:01 |
| 1 | NESTED LOOPS | | 2 | 132 | 2 (0)|
00:00:01 |
| 2 | TABLE ACCESS BY INDEX ROWID| PERSON | 1 | 40 | 1 (0)|
00:00:01 |
|* 3 | INDEX UNIQUE SCAN | PERSON_PK | 1 | | 0 (0)|
00:00:01 |
|* 4 | INDEX RANGE SCAN | ORDERS_PK | 2 | 52 | 1 (0)|
00:00:01 |
Predicate Information (identified by operation id)
3 - access("P"."P_ID"=1)
4 - access("O"."P_ID"=1)
Note
dynamic sampling used for this statement
`
| 0 | SELECT STATEMENT | | 1 | 29 | 2 (0)| 00:00:01 | | 1 | NESTED LOOPS | | 1 | 29 | 2 (0)| 00:00:01 | | 2 | TABLE ACCESS BY INDEX ROWID| RP_TRANSACTION | 1 | 12 | 1 (0)| 00:00:01 | |* 3 | INDEX UNIQUE SCAN | RP_TRANSACTION_PK | 1 | | 0 (0)| 00:00:01 | | 4 | TABLE ACCESS BY INDEX ROWID| RP_REQUEST | 279 | 4743 | 1 (0)| 00:00:01 | |* 5 | INDEX UNIQUE SCAN | RP_REQUEST_PK | 1 | | 0 (0)| 00:00:01 | Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("TRANSACTION_ID"=18516648) 5 - access("REQ"."REQUEST_ID"="TRANS"."REQUEST_ID")
----以下是我原来的帖子
据我所知,oracle首先使用临时空间执行视图(逻辑视图),然后执行过滤..所以你的查询基本上与
相同 SELECT *
FROM(SELECT *
来自P P,ORDERS O.
在哪里P.P_ID = O.P_ID
)其中P_ID ='1234'
我认为你不能在逻辑视图上创建索引(物化视图使用索引)
另外,您应该知道,每次使用时都会执行MY_VIEW查询 选择 * 来自MY_VIEW 其中P_ID ='1234'。
我的意思是每一次。当然,对于表现问题来说,这不是一个好主意