如何从巨大的表

时间:2016-03-09 08:11:19

标签: sql oracle performance indexing oracle11g

我目前有一个过程需要很长时间(一小时+ - )。

这个过程基本上是这样做的:

首先,它从一个表连接到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是否允许),因为这是一个小表。

限制

  1. 我无法更改大表(STG_SCD)上的索引
  2. 我可以在其他表上添加索引,但只有充分的理由,因为它可能会损害使用此表的其他进程的性能。
  3. 隐式连接语法是通过我的程序生成的,所以不需要在那里发表评论。

    提前多多感谢!

    P.S。第一个选择左连接到第二个选择大约需要30-60分钟。

2 个答案:

答案 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)

感谢您的所有尝试:)

相关问题