(Oracle Performance) Будет ли запрос, основанный на представлении, ограничивать представление с помощью предложения where? - PullRequest
2 голосов
/ 22 марта 2010

В Oracle (10g), когда я использую представление (не материализованное представление), учитывает ли 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 будет выполнять мой запрос к представлению, которое не имеет индекса, а не к базовой таблице, которая имеет индекс?

Ответы [ 2 ]

6 голосов
/ 22 марта 2010

Сначала запрос не будет выполнен.Если у вас есть индекс для P_ID, он будет использоваться.

План выполнения такой же, как если бы вы объединили и код представления, и предложение WHERE в один оператор выбора.

Вы можете попробовать это сами:

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|
---------------------------------------------------------------------------------
0 голосов
/ 22 марта 2010

WOW !!Это интересно .. У меня есть два разных плана объяснения, зависящих от разных объемов данных и запросов внутри логического представления (это мое предположение)

  1. Исходный вопрос: он определенно сначала выполняет фильтрацию.У меня есть небольшое количество данных (<10 в общей сложности) в этой тестовой таблице.<pre> ` | 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 <ul> <li>dynamic sampling used for this statement `
  2. Однако, когда данные становятся больше (хотя бы несколько сотен, хотя 300–400) и запрос представления становится сложным (с использованием «connect by» и т. Д.),план изменился, я думаю ...
|   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") 

---- Ниже мой оригинальный пост

Насколько я знаю, оракул сначала выполняет представление (логическое представление), используявременное пространство, а затем выполнить фильтр .. Таким образом, ваш запрос в основном такой же, как

SELECT *
FROM (SELECT *
ОТ ЧЕЛОВЕКА P, ЗАКАЗЫ O ГДЕ P.P_ID = O.P_ID)P_ID = '1234'

Я не думаю, что вы можете создать индекс для логического представления (материализованное представление использует индекс)

Кроме того, вы должны знать, что вы выполнили бы запрос для MY_VIEW,каждый раз, когда вы используете select * из MY_VIEW, где P_ID = '1234'.

Я имею в виду каждый раз.Естественно, это не очень хорошая идея для производительности

...