2

我正在运行 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。所以我想弄清楚是否有什么办法可以让第一个查询运行得更快。

这是执行计划的截图:

在此处输入图像描述

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

谢谢!

4

2 回答 2

0

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

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

第三,您可以尝试将 count(distinct) 移动到另一个联接甚至子查询,并检查性能是否发生变化。

于 2013-09-12T15:04:57.233 回答
0

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

请注意 MAX_MEM_USED、NUMBER_OF_PASSES 和 TEMPSEG_SIZE。

如果遍数大于 1,那么您将进行多遍排序,这是一个非常慢的操作。一次通过还不错,但请注意查询需要多大的临时段,因为这决定了在排序操作期间使用了多少 i/o。

对此的修复是:

  1. 增加排序的内存分配,无论是整个实例还是特别是会话,或者......
  2. 减少您正在排序的数据量。这主要意味着减少排序的键大小,当您在 group by 中有依赖于其他元素的元素时,有时可以这样做。您可以仅按所需元素进行分组,然后加入该结果集以获取其他相关元素。
  3. 使用并行查询。
于 2013-09-20T13:28:49.203 回答