优化查询和导出

时间:2016-03-17 14:56:08

标签: sql oracle oracle-sqldeveloper

下面的代码给出了结果,但执行需要5分钟,之后我需要将数据导出到文本。有120万条记录,即使在9小时后也无法出口。

您能否帮助优化查询并提高执行性能,还有助于加快导出速度?

我不能在SQL开发人员中使用offset和fetch。

WITH NAGP AS
         (SELECT Company_common_id, PROFILECLASSVALUE
            FROM (SELECT /* + PARALLEL( gp, 20)*/
                        co.Company_common_id,
                         gp.PROFILECLASSVALUE,
                         RANK() OVER(PARTITION BY co.Company_common_id ORDER BY co.commit_date DESC) RK
                    FROM stg_cmat.cmat_sync_ref co, stg_cmat.cmat_enrich_ref gp
                   WHERE     gp.transaction_id = co.transaction_id
                         AND co.event = 'ENRICHMENT'
                         AND gp.profilename = 'EnrichmentProfile'
                         AND gp.PROFILECLASSNAME = 'NAGP ID')
           WHERE RK = 1)
SELECT EC.system_serial_number,
       EC.cmat_customer_id EC_cmat_customer_id,
       EC.system_status EC_system_status,
       (SELECT n.PROFILECLASSVALUE
          FROM NAGP n
         WHERE n.Company_common_id = EC.cmat_customer_id)
           EC_NAGP_ID,
       SN.cmat_customer_id SN_cmat_customer_id,
       SN.system_status SN_system_status,
       (SELECT n.PROFILECLASSVALUE
          FROM NAGP n
         WHERE n.Company_common_id = SN.cmat_customer_id)
           SN_NAGP_ID
  FROM (SELECT a.system_serial_number,
               a.role_id,
               a.cmat_customer_id,
               s.system_status
          FROM EIM.eim_latest_sys_party_role a, eim.eim_system s
         WHERE     a.system_serial_number = s.system_serial_number(+)
               AND a.role_id = 1) EC,
       (SELECT z.system_serial_number,
               a.role_id,
               a.cmat_customer_id,
               s.system_status
          FROM EIM.eim_latest_sys_party_role a, eim.eim_system s
         WHERE     a.system_serial_number = s.system_serial_number(+)
               AND a.role_id = 19) SN
 WHERE EC.system_serial_number = SN.system_serial_number;

我们在执行后得到的结果。

SYSTEM_SERIAL_NUMBER  EC_CMAT_CUSTOMER_ID  EC_SYSTEM_STATUS  EC_NAGP_ID SN_CMAT_CUSTOMER_ID  SN_SYSTEM_STATUS  SN_NAGP_ID
105977453         6000789              ACTIVE            357033     6000789              ACTIVE            357033
105977457         6000789              ACTIVE            357033     6000789              ACTIVE            357033
105977459         6000789              ACTIVE            357033     6000789              ACTIVE            357033
105977460         6000789              ACTIVE            357033     6000789              ACTIVE            357033
105977462         6000789              ACTIVE            357033     6000789              ACTIVE            357033
1059776           5016269              ACTIVE            256841     5016269              ACTIVE            256841
1059781           5023315              DECOMISSIONED     256842     5023315              DECOMISSIONED     256842
1059783           5023315              DECOMISSIONED     256842     5023315              DECOMISSIONED     256842
1059785           5023315              DECOMISSIONED     256842     5023315              DECOMISSIONED     256842
1059792           5016269              DECOMISSIONED     256841     5016269              DECOMISSIONED     256841
105980000         14031077             ACTIVE            14032472   14031077             ACTIVE            14032472

1 个答案:

答案 0 :(得分:0)

由于您还没有提供有关表格或数据的信息,因此这是一个完整的猜测,但您可能会发现使用以下查询有一些好处:

with latest_co_transaction as (select company_common_id,
                                      max(transaction_id) keep (dense_rank first order by commit_date_desc)
                               from   stg_cmat.cmat_sync_ref
                               where  event = 'ENRICHMENT'
                               group by company_common_id),
                      nagp as (select co.company_common_id,
                                      gp.profileclassvalue
                               from   latest_co_transaction co
                                      inner join stg_cmat.cmat_enrich_ref gp on (gp.transaction_id = co.transaction_id)
                               where  gp.profilename = 'EnrichmentProfile'
                               and    gp.profileclassname = 'NAGP ID'),
                     ec_sn as (select a.system_serial_number,
                                      max(case when role_id = 1 then a.cmat_customer_id end) ec_cmat_customer_id,
                                      max(case when role_id = 1 then s.system_status end) ec_system_status,
                                      max(case when role_id = 19 then a.cmat_customer_id end) sn_cmat_customer_id,
                                      max(case when role_id = 19 then s.system_status end) sn_system_status
                               from   eim.eim_latest_sys_party_role a
                                      left outer join eim.eim_system s on (a.system_serial_number = s.system_serial_number)
                               where  a.role_id in (1, 19)
                               group by a.sstem_serial_number)
select ec.system_serial_number,
       ec_cmat_customer_id,
       ec_system_status,
       (select n.profileclassvalue
        from   nagp n
        where  n.company_common_id = ec_cmat_customer_id) ec_nagp_id,
       sn_cmat_customer_id,
       sn_system_status,
       (select n.profileclassvalue
        from   nagp n
        where  n.company_common_id = sn_cmat_customer_id)  sn_nagp_id
from ec_sn;

这假设system_serial_numberrole_id列在eim.eim_latest_sys_party_role表中是唯一的,以启用数据的旋转。不知道eim.eim_latest_sys_party_roleeim.eim_system以及索引中有多少数据,您可能会发现执行分组比执行联接更有效。或者它可能不是。

关于您的nagp子查询,我将其拆分为两个,过滤stg_cmat.cmat_sync_ref表中的行以获取最新transaction_id的{​​{1}}在将其加入commit_date表之前。这有助于加快查询速度。

我已经将标量子查询与nagp放在一起,因为看起来你可能会从标量子查询缓存中受益。

您可能还会发现添加以下索引的好处:

  • stg_cmat.cmat_sync_ref:(company_common_id,commit_date,transaction_id)
  • stg_cmat.cmat_enrich_ref :( transaction_id,profilename,profileclassname,profileclassvalue)
  • eim.eim_latest_sys_party_role(system_serial_number,role_id,cmat_customer_id)
  • eim.eim_system(system_serial_number,system_status)