oracle优化distinct,oracle中使用group by优化distinct

今天mentor给了一个sql语句优化的任务。(环境是sql developer)有一个语句执行很慢,查询出来的结果有17544条记录,但需970秒,速度很慢。语句是这样的:

SELECT DISTINCT 'AMEND_NEW',

reporttitle,

reportsubtitle,

cab_cab_transactions.branchcode,

cab_cab_transactions.prtfo_cd,

cab_cab_transactions.sstm_scrty_id,

cab_cab_transactions.sstm_trx_id,

cab_cab_transactions.trde_dttm,

cab_cab_transactions.efcte_dttm,

cab_cab_transactions.due_stlmnt_dt,

cab_cab_transactions.cncl_efcte_dttm,

cab_cab_transactions.trde_sstm_id,

cab_cab_transactions.trx_type_cd,

cab_cab_transactions.trx_type_dscrn,

cab_cab_transactions.trx_subtype_cd,

cab_cab_transactions.trde_stat_flg,

cab_cab_transactions.csh_cr_dr_indcr,

cab_cab_transactions.long_shrt_indcr,

cab_cab_transactions.lcl_crncy,

cab_cab_transactions.stlmt_crncy,

cab_cab_transactions.nomin_qty,

cab_cab_transactions.price,

cab_cab_transactions.lcl_cst,

cab_cab_transactions.prtfo_cst,

cab_cab_transactions.lcl_book_cst,

cab_cab_transactions.prtfo_book_cst,

cab_cab_transactions.lcl_sell_prcds,

cab_cab_transactions.prtfo_sell_prcds,

cab_cab_transactions.lcl_gnls,

cab_cab_transactions.prtfo_gnls,

cab_cab_transactions.lcl_acrd_intrt,

cab_cab_transactions.prtfo_acrd_intrt,

cab_cab_transactions.stlmt_crncy_stlmt_amt,

cab_cab_transactions.lcl_net_amt,

cab_cab_transactions.prtfo_net_amt,

cab_cab_transactions.fx_bght_amt,

cab_cab_transactions.fx_sold_amt,

cab_cab_transactions.prtfo_crncy_stlmt_amt,

cab_cab_transactions.prtfo_net_incme,

cab_cab_transactions.dvnd_crncy_net_incme,

cab_cab_transactions.dvnd_type_cd,

cab_cab_transactions.lcl_intrt_pd_rec,

cab_cab_transactions.prtfo_intrt_pd_rec,

cab_cab_transactions.lcl_dvdnd_pd_rec,

cab_cab_transactions.prtfo_dvdnd_pd_rec,

cab_cab_transactions.lcl_sundry_inc_pd_rec,

cab_cab_transactions.prtfo_sundry_inc_pd_rec,

cab_cab_transactions.bnk_csh_cptl_secid,

cab_cab_transactions.bnk_csh_inc_secid,

cab_cab_transactions.reportdate,

cab_cab_transactions.filename,

sysdate,

'e483448'

FROM cab_cfg_trx_type_mapping RIGHT JOIN(cab_cab_tran_adjustments

INNER JOIN cab_cab_transactions ON(cab_cab_transactions.branchcode = cab_cab_tran_adjustments.branchcode )

AND(cab_cab_tran_adjustments.sstm_trx_id = cab_cab_transactions.sstm_trx_id)) ON(cab_cfg_trx_type_mapping.cab_trx_type_cd = cab_cab_transactions.trx_type_cd)

AND(nvl(cab_cfg_trx_type_mapping.cab_trx_subtype_cd,' ') = nvl(cab_cab_transactions.trx_subtype_cd,' ')

AND (cab_cfg_trx_type_mapping.branchcode=cab_cab_transactions.branchcode))

WHERE cab_cab_transactions.prtfo_cd IN

(SELECT DISTINCT prtfo_cd

FROM cab_cab_valuations_working

WHERE created_by = 'e483448'

AND branchcode='ISA')

AND cab_cab_tran_adjustments.efcte_dttm > '2011-07-31'

AND cab_cab_tran_adjustments.efcte_dttm <= '2011-08-31'

AND eff_trde_stat_flg <> 'X'

AND cab_cab_transactions.branchcode = 'ISA'

AND cab_cab_tran_adjustments.branchcode = 'ISA'

AND(cab_cfg_trx_type_mapping.cab_reportgroup = 'CABValuation' OR cab_cfg_trx_type_mapping.cab_reportgroup IS NULL)

问题在distinct上面,它会导致对全表扫描,而且会导致排序,然后删除重复的记录,所以速度很慢,因此需要优化distinct。查了不少资料,并逐一尝试,最后发现了一个非常可观的优化结果,用group by。语句如下:

SELECT 'AMEND_NEW',

reporttitle,

reportsubtitle,

cab_cab_transactions.branchcode,

cab_cab_transactions.prtfo_cd,

cab_cab_transactions.sstm_scrty_id,

cab_cab_transactions.sstm_trx_id,

cab_cab_transactions.trde_dttm,

cab_cab_transactions.efcte_dttm,

cab_cab_transactions.due_stlmnt_dt,

cab_cab_transactions.cncl_efcte_dttm,

cab_cab_transactions.trde_sstm_id,

cab_cab_transactions.trx_type_cd,

cab_cab_transactions.trx_type_dscrn,

cab_cab_transactions.trx_subtype_cd,

cab_cab_transactions.trde_stat_flg,

cab_cab_transactions.csh_cr_dr_indcr,

cab_cab_transactions.long_shrt_indcr,

cab_cab_transactions.lcl_crncy,

cab_cab_transactions.stlmt_crncy,

cab_cab_transactions.nomin_qty,

cab_cab_transactions.price,

cab_cab_transactions.lcl_cst,

cab_cab_transactions.prtfo_cst,

cab_cab_transactions.lcl_book_cst,

cab_cab_transactions.prtfo_book_cst,

cab_cab_transactions.lcl_sell_prcds,

cab_cab_transactions.prtfo_sell_prcds,

cab_cab_transactions.lcl_gnls,

cab_cab_transactions.prtfo_gnls,

cab_cab_transactions.lcl_acrd_intrt,

cab_cab_transactions.prtfo_acrd_intrt,

cab_cab_transactions.stlmt_crncy_stlmt_amt,

cab_cab_transactions.lcl_net_amt,

cab_cab_transactions.prtfo_net_amt,

cab_cab_transactions.fx_bght_amt,

cab_cab_transactions.fx_sold_amt,

cab_cab_transactions.prtfo_crncy_stlmt_amt,

cab_cab_transactions.prtfo_net_incme,

cab_cab_transactions.dvnd_crncy_net_incme,

cab_cab_transactions.dvnd_type_cd,

cab_cab_transactions.lcl_intrt_pd_rec,

cab_cab_transactions.prtfo_intrt_pd_rec,

cab_cab_transactions.lcl_dvdnd_pd_rec,

cab_cab_transactions.prtfo_dvdnd_pd_rec,

cab_cab_transactions.lcl_sundry_inc_pd_rec,

cab_cab_transactions.prtfo_sundry_inc_pd_rec,

cab_cab_transactions.bnk_csh_cptl_secid,

cab_cab_transactions.bnk_csh_inc_secid,

cab_cab_transactions.reportdate,

cab_cab_transactions.filename,

sysdate,

'e483448'

FROM cab_cfg_trx_type_mapping RIGHT JOIN(cab_cab_tran_adjustments

INNER JOIN cab_cab_transactions ON(cab_cab_transactions.branchcode = cab_cab_tran_adjustments.branchcode )

AND(cab_cab_tran_adjustments.sstm_trx_id = cab_cab_transactions.sstm_trx_id)) ON(cab_cfg_trx_type_mapping.cab_trx_type_cd = cab_cab_transactions.trx_type_cd)

AND(nvl(cab_cfg_trx_type_mapping.cab_trx_subtype_cd,' ') = nvl(cab_cab_transactions.trx_subtype_cd,' ')

AND (cab_cfg_trx_type_mapping.branchcode=cab_cab_transactions.branchcode))

WHERE cab_cab_transactions.prtfo_cd IN

(SELECT DISTINCT prtfo_cd

FROM cab_cab_valuations_working

WHERE created_by = 'e483448'

AND branchcode='ISA')

AND cab_cab_tran_adjustments.efcte_dttm > '2011-07-31'

AND cab_cab_tran_adjustments.efcte_dttm <= '2011-08-31'

AND eff_trde_stat_flg <> 'X'

AND cab_cab_transactions.branchcode = 'ISA'

AND cab_cab_tran_adjustments.branchcode = 'ISA'

AND(cab_cfg_trx_type_mapping.cab_reportgroup = 'CABValuation' OR cab_cfg_trx_type_mapping.cab_reportgroup IS NULL)

GROUP BY reporttitle,

reportsubtitle,

cab_cab_transactions.branchcode,

cab_cab_transactions.prtfo_cd,

cab_cab_transactions.sstm_scrty_id,

cab_cab_transactions.sstm_trx_id,

cab_cab_transactions.trde_dttm,

cab_cab_transactions.efcte_dttm,

cab_cab_transactions.due_stlmnt_dt,

cab_cab_transactions.cncl_efcte_dttm,

cab_cab_transactions.trde_sstm_id,

cab_cab_transactions.trx_type_cd,

cab_cab_transactions.trx_type_dscrn,

cab_cab_transactions.trx_subtype_cd,

cab_cab_transactions.trde_stat_flg,

cab_cab_transactions.csh_cr_dr_indcr,

cab_cab_transactions.long_shrt_indcr,

cab_cab_transactions.lcl_crncy,

cab_cab_transactions.stlmt_crncy,

cab_cab_transactions.nomin_qty,

cab_cab_transactions.price,

cab_cab_transactions.lcl_cst,

cab_cab_transactions.prtfo_cst,

cab_cab_transactions.lcl_book_cst,

cab_cab_transactions.prtfo_book_cst,

cab_cab_transactions.lcl_sell_prcds,

cab_cab_transactions.prtfo_sell_prcds,

cab_cab_transactions.lcl_gnls,

cab_cab_transactions.prtfo_gnls,

cab_cab_transactions.lcl_acrd_intrt,

cab_cab_transactions.prtfo_acrd_intrt,

cab_cab_transactions.stlmt_crncy_stlmt_amt,

cab_cab_transactions.lcl_net_amt,

cab_cab_transactions.prtfo_net_amt,

cab_cab_transactions.fx_bght_amt,

cab_cab_transactions.fx_sold_amt,

cab_cab_transactions.prtfo_crncy_stlmt_amt,

cab_cab_transactions.prtfo_net_incme,

cab_cab_transactions.dvnd_crncy_net_incme,

cab_cab_transactions.dvnd_type_cd,

cab_cab_transactions.lcl_intrt_pd_rec,

cab_cab_transactions.prtfo_intrt_pd_rec,

cab_cab_transactions.lcl_dvdnd_pd_rec,

cab_cab_transactions.prtfo_dvdnd_pd_rec,

cab_cab_transactions.lcl_sundry_inc_pd_rec,

cab_cab_transactions.prtfo_sundry_inc_pd_rec,

cab_cab_transactions.bnk_csh_cptl_secid,

cab_cab_transactions.bnk_csh_inc_secid,

cab_cab_transactions.reportdate,

cab_cab_transactions.filename

最后执行时间只有15.1秒,快了60多倍,不得不说这优化效果还是很可观的。不过查了很多资料,仍然没有发现合理地解释:为什么distinct 和group by的效率会有这么大差别。查的很多资料,讲的基本都是两者相差不大,实现也差不多。有待解决。

DISTINCT和GROUP BY这两者本质上应该没有可比性,distinct 取出唯一列,group by 是分组,但有时候在优化的时候,在没有聚合函数的时候,他们查出来的结果也一样。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Oracle使用DISTINCT关键字可以去除查询结果的重复行。然而,DISTINCT操作会对查询的性能产生影响,特别是当查询的数据量非常大时。因此,在优化Oracle查询性能时,需要考虑如何优化DISTINCT操作。 以下是一些优化DISTINCT操作的技巧: 1. 使用索引:如果查询包含DISTINCT操作的列已经建立了索引,那么查询将更快。因此,如果可能的话,应该在DISTINCT操作的列上建立索引。 2. 使用GROUP BY替代DISTINCT:在某些情况下,可以使用GROUP BY替代DISTINCT。例如,以下查询: SELECT DISTINCT column1, column2 FROM table1; 可以改写为: SELECT column1, column2 FROM table1 GROUP BY column1, column2; 这种方法可能比DISTINCT更快,因为GROUP BY可以利用索引来优化查询。 3. 使用子查询:在某些情况下,可以使用子查询替代DISTINCT。例如,以下查询: SELECT DISTINCT column1 FROM table1 WHERE column2 = 'value'; 可以改写为: SELECT column1 FROM (SELECT column1 FROM table1 WHERE column2 = 'value') WHERE ROWNUM = 1; 这种方法可以避免使用DISTINCT,并且可以利用索引来优化查询。 4. 避免使用多个DISTINCT:在某些情况下,查询可能需要使用多个DISTINCT操作。但是,使用多个DISTINCT操作会对查询性能产生很大的影响。因此,尽可能避免使用多个DISTINCT操作。 总之,在优化Oracle查询性能时,需要考虑如何优化DISTINCT操作。可以使用索引、GROUP BY、子查询和避免使用多个DISTINCT等技巧来优化查询的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值