致力于提高决策中心的绩效,我们确定的瓶颈之一就是数据库.
所以我想知道,oracle是否为其视图编制了执行计划?
让我们假设我10000
在请求期间使用了定义的查询次数.查询看起来像:
select A, B, C from aTbl, bTbl left join cTbl on bTbl.cTblID = cTbl.objectkey where aTbl.objectkey = bTbl.parentkey
在代码中我想用额外的过滤参数获取上面查询的结果,例如: WHERE aTbl.flag1 = <
现在我有两个选择:
使用上面的内容创建预准备语句SQL
,然后重用该对象.
将上述内容select (aTbl, bTbl, cTbl)
放入a VIEW
,然后在此视图上创建预准备语句,从而使预编译的Oracle执行计划受益.
你会建议什么?
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
将选择推动谓词,这是可能的);
首次调用时编译;
再次调用时重复使用.