【发布时间】:2019-09-01 21:08:24
【问题描述】:
我有一个非常复杂的视图,格式如下
create or replace view loan_vw as
select * from (with loan_info as (select loan_table.*,commission_table.*
from loan_table,
commission_table where
contract_id=commission_id)
select /*complex transformations */ from loan_info
where type <> 'PRINCIPAL'
union all
select /*complex transformations */ from loan_info
where type = 'PRINCIPAL')
现在如果我执行以下操作,则选择查询挂起
select * from loan_vw where contract_id='HA001234TY56';
但是,如果我在子查询重构中硬编码或在同一会话中使用包级变量,查询会在一秒钟内返回
create or replace view loan_vw as
select * from (with loan_info as (select loan_table.*,commission_table.*
from loan_table,
commission_table where
contract_id=commission_id
and contract_id='HA001234TY56'
)
select /*complex transformations */ from loan_info
where type <> 'PRINCIPAL'
union all
select /*complex transformations */ from loan_info
where type = 'PRINCIPAL')
由于我使用业务对象,我不能使用包级变量
所以我的问题是Oracle中有一个提示告诉优化器首先检查子查询重构中loan_vw中的contract_id
根据要求,使用的分析函数如下
select value_date, item, credit_entry, item_paid
from (
select value_date, item, credit_entry, debit_entry,
greatest(0, least(credit_entry, nvl(sum(debit_entry) over (), 0)
- nvl(sum(credit_entry) over (order by value_date
rows between unbounded preceding and 1 preceding), 0))) as item_paid
from your_table
)
where item is not null;
在遵循 Boneist 和 MarcinJ 的建议后,我删除了子查询重构 (CTE),并编写了一个长查询,如下所示,将性能从 3 分钟提高到 0.156 秒
create or replace view loan_vw as
select /*complex transformations */
from loan_table,
commission_table where
contract_id=commission_id
and loan_table.type <> 'PRINCIPAL'
union all
select /*complex transformations */
from loan_table,
commission_table where
contract_id=commission_id
and loan_table.type = 'PRINCIPAL'
【问题讨论】:
-
我认为你在 contract_id 列上有索引,因此它在硬编码时得到了更快的优化
-
yes index is there on contract_id
-
所以在创建视图时它挂起,因为当您从视图中查询时,优化器没有可用的索引工具,所以它变慢或挂起基于它显示的数据量行为
-
是的,基于它挂起的数据量,但由于我正在传递contract_id,我希望它首先查看loan_info
-
尝试使用可能对您有所帮助的物化视图docs.oracle.com/cd/A97630_01/server.920/a96567/repmview.htm
标签: sql oracle performance subquery query-optimization