Oracle / SQL - 需要帮助优化COUNT DISTINCT查询

时间:2013-09-12 13:52:37

标签: sql oracle oracle10g query-optimization distinct

我正在运行Oracle 10g。以下查询,大约需要25分钟才能运行。 我查看了执行计划,据我所知,80%的费用是DISTINCT COUNT

SELECT STG.dts_start_dt_wid, 
   ML.sales_org_wid, 
   ML.cost_center_wid, 
   ML.chnl_type_wid, 
   ML.x_generic_lead_source_wid, 
   ML.x_specific_lead_source_wid, 
   ML.x_order_category_wid, 
   Count(DISTINCT ML.row_wid) AS TOTAL_ACTIVE_LICENSES 
FROM   wc_lsp_master_license_d ML, 
   wc_reflex_daily_activity_a_stg STG 
WHERE  ML.license_class = 'REFLEX' 
   AND STG.dts_start_dt_wid BETWEEN ML.extensions_start_dt_wid AND 
                                    ML.extensions_end_dt_wid 
   AND ML.license_name NOT LIKE '%demo@rosettastone.com' 
GROUP  BY STG.dts_start_dt_wid, 
      ML.sales_org_wid, 
      ML.cost_center_wid, 
      ML.chnl_type_wid, 
      ML.x_generic_lead_source_wid, 
      ML.x_specific_lead_source_wid, 
      ML.x_order_category_wid; 

不幸的是,我需要计算不同的row_wids。所以我想弄清楚我能做些什么来让第一个查询运行得更快。

以下是执行计划的屏幕截图:

enter image description here

对此的任何帮助或反馈都会很棒。

谢谢!

2 个答案:

答案 0 :(得分:0)

首先,验证您在WHERE子句中使用的列(以及来自COUNT DISTINCT的列)是否具有索引(或者是主/唯一/外键)。

其次,检查是否可以添加其他WHERE子句来替换COUNT中的DISTINCT,或者甚至将其替换为非常优化的COUNT(*)。

第三,您可以尝试将计数(不同)移动到另一个连接或甚至子查询,并检查性能是否发生变化。

答案 1 :(得分:0)

如果按操作排序组的成本很高,则很可能是由于排序溢出到磁盘。在查询运行时,您可以使用V$SQL_WORKAREA_ACTIVE进行检查。

请注意MAX_MEM_USED,NUMBER_OF_PASSES和TEMPSEG_SIZE。

如果传球次数大于1,那么你有多次通过排序,这是一个非常慢的操作。一次传递并不算太糟糕,但请注意查询所需的临时段有多大,因为它决定了在排序操作期间使用了多少i / o。

对此的修复是:

  1. 为整个实例或特别是会话增加排序的内存分配,或者......
  2. 减少要排序的数据量。这主要意味着减少排序的密钥大小,当组中的元素依赖于其他元素时,有时可以执行此操作。您只能按必需元素进行分组,然后连接到该结果集以获取其他相关元素。
  3. 使用并行查询。