Oracle
может выдвинуть предикат в представление, если думает, что это улучшит план.
Если вы хотите избежать этого, вы можете использовать одно из следующих:
- Добавить
/*+ NO_MERGE */
или /*+ NO_PUSH_PRED */
подсказку в определение вида
- Добавьте подсказку
/*+ NO_MERGE (view) */
или /*+ NO_PUSH_PRED (view) */
в запрос, который использует представление.
Если вы хотите форсировать это, используйте их couterparts /*+ PUSH_PRED */
и /*+ MERGE */
Что касается производительности, то нет никакой разницы между использованием определенного представления (если это, конечно, не MATERIALIZED VIEW
) или встроенным представлением (т.е. подзапросом).
Oracle
компилирует планы не для видов, а для точных SQL
текстов.
То есть для следующих утверждений:
SELECT A, B, C
FROM aTbl, bTbl
LEFT JOIN cTbl ON
bTbl.cTblID = cTbl.objectkey
WHERE aTbl.objectkey = bTbl.parentkey
AND aTbl.flag1 = :NUMBER
SELECT *
FROM
(
SELECT A, B, C, flag1
FROM aTbl, bTbl
LEFT JOIN cTbl ON
bTbl.cTblID = cTbl.objectkey
WHERE aTbl.objectkey = bTbl.parentkey
)
WHERE flag1 = :NUMBER
/*
CREATE VIEW v_abc AS
SELECT A, B, C, flag1
FROM aTbl, bTbl
LEFT JOIN cTbl ON
bTbl.cTblID = cTbl.objectkey
WHERE aTbl.objectkey = bTbl.parentkey
*/
SELECT A, B, C
FROM v_abc
WHERE flag1 = :NUMBER
план будет:
- Будьте такими же (если
Oracle
выберет предикат, что более чем вероятно);
- Быть скомпилированным при первом вызове;
- Повторно использовать при повторном вызове.