我目前有一个过程需要很长时间(一小时+ - )。
这个过程基本上是这样做的:
首先,它从一个表连接到VIEW -
SELECT * FROM
STG_CRM, V_CRM
WHERE
STG_CRM.CRM_CASE_ID=V_CRM.CASE_ID(+)
视图DDL:
create or replace view stg_admin.v_crm as
select t.case_id
from crm_case t, dim_crm x
where t.case_id=x.crm_case_id;
STG_CRM - 200k记录 - 没有索引。
DIM_CRM - 90MIL记录 - 已编入索引(crm_case_id - 唯一)。
CRM_CASE - 200k记录 - 没有索引。
到目前为止,一切都还不重(约2-3分钟),然后左边连接到另一个VIEW,目前是最重的选择(从视图中选择*是10分钟)。
查看DDL - 我正在考虑两个不同的查询:
select t.crm_case_id,s.customer_key
from stg_crm t, stg_scd s
where t.account_number=s.account_number
and t.case_create_date between s.start_date and s.end_date;
或者:
select t.crm_case_id,
(select min(s.customer_key) keep (dense_rank first order by s.end_date asc)
from stg_scd s
where t.account_number = s.account_number and
t.case_create_date <= s.end_date
) as customer_key
from stg_crm t
表stg_scd - 已建立索引的500MIL记录(customer_key,start_date,end_date) - 每天由end_date分区的UNIQUE。
现在目前这两个查询花了很长时间,第二个花了更长时间。我的猜测是因为它没有使用索引,因为start_date不是用于过滤,但我不知道如何添加它。
我的问题是:如何让它更快?如果我在create_date上的STG_CRM上添加一个索引,它会有帮助吗?(我甚至不知道DBA是否允许),因为这是一个小表。
限制:
隐式连接语法是通过我的程序生成的,所以不需要在那里发表评论。
提前多多感谢!
P.S。第一个选择左连接到第二个选择大约需要30-60分钟。
答案 0 :(得分:0)
由于您正在聚合来自非常大的表的数据(正如您在第二个查询选项中所做的那样),因此使用query_rewrite提前计算这些值的结果可能会获得一些性能优势。这是一篇涵盖此功能使用的论文 - http://gerardnico.com/wiki/database/oracle/query_rewriting
您还可以找到许多其他使用此功能的最佳实践示例,它在调整数据仓库查询方面非常有价值。
祝你好运!答案 1 :(得分:0)
我设法解决了这个问题!
我错过了两件事:
1)stg_scd的统计信息,我们在向表中添加分区后禁用,并且在添加每个分区后忘记添加统计信息。
2)在stg_crm上添加索引(account_number,case_create_date)
感谢您的所有尝试:)