【问题标题】:Oracle/SQL - Need help optimizing COUNT DISTINCT queryOracle/SQL - 需要帮助优化 COUNT DISTINCT 查询
【发布时间】:2013-09-16 22:55:15
【问题描述】:

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

这是执行计划的截图:

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

谢谢!

【问题讨论】:

  • 。 .表之间真的没有引用许可证之类的连接条件吗?
  • 1.运行alter session set statistics_level = all; 2. 在同一会话中运行您的查询 3. 查询完成后运行SELECT t.* FROM v$sql s, table(DBMS_XPLAN.DISPLAY_CURSOR(s.sql_id, s.child_number, 'ALLSTATS LAST')) t WHERE upper(sql_text) LIKE upper('%Count(DISTINCT ML.row_wid) AS TOTAL_ACTIVE_LICENSES%'); 并在此处发布输出
  • 戈登林诺夫,谢谢你的回复。
  • 能否请您发布您的表创建语句和键? @Sbejavada

标签: sql oracle oracle10g query-optimization distinct


【解决方案1】:

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

注意 MAX_MEM_USED、NUMBER_OF_PASSES 和 TEMPSEG_SIZE。

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

对此的修复是:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-03
      • 1970-01-01
      相关资源
      最近更新 更多