降低oracle sql查询的成本

时间:2016-03-14 12:45:09

标签: sql oracle

我使用以下查询来查看我的所有对帐单和付款的概述,按年份分组:

WITH FILTERED_BALANCES AS
(
    SELECT FACT_AS_BALANCE.* 
    FROM FACT_AS_BALANCE 
      JOIN DIM_AS_CHARACTERISTICS ON FACT_AS_BALANCE.BALANCE_TYPE_ID = DIM_AS_CHARACTERISTICS.ID 
    WHERE DIM_AS_CHARACTERISTICS.TRANSACTION_INTRADAY_FLAG = 'N'
      AND DIM_AS_CHARACTERISTICS.BALANCE_CLOSING_FLAG = 'Y'
)
SELECT DD.WEEK_OF_YEAR, DD.CAL_YEAR, COALESCE(COUNT(DISTINCT FPP.ID),0) AS PAYMENTS, 
       COALESCE(COUNT(DISTINCT FAB.ACCOUNT_STATEMENT_ID),0) AS STATEMENTS
FROM FACT_PAY_PAYMENT FPP
  FULL OUTER JOIN FILTERED_BALANCES FAB ON FAB.BALANCE_DATE_ID = FPP.REQUESTED_EXECUTION_DATE_ID
  JOIN DIM_DATE DD ON FPP.REQUESTED_EXECUTION_DATE_ID = DD.ID OR FAB.BALANCE_DATE_ID = DD.ID 
GROUP BY DD.CAL_YEAR, DD.WEEK_OF_YEAR;

这给出了以下输出:

Example of output

这样可行,但由于我在查询中使用完全外连接,因此性能严重泄漏。您可以在下面找到Oracle SQL开发人员的解释计划: enter image description here

问题是降低此查询的成本。我试图拆分付款和报表,但我有一个逻辑问题。当我在一周内付款但没有发言时,报表结果表没有一周没有发表声明的条目。

如何以更好的性能解决此问题?

1 个答案:

答案 0 :(得分:0)

在不了解数据库结构和拥有样本数据的情况下,很难帮助您。请提供更多信息。

仅使用您需要的列替换WITH子句中的完整表选择。 将它们编入索引。

WITH FILTERED_BALANCES AS
(
    SELECT FACT_AS_BALANCE.BALANCE_DATE_ID
    FROM FACT_AS_BALANCE 
      JOIN DIM_AS_CHARACTERISTICS ON FACT_AS_BALANCE.BALANCE_TYPE_ID = DIM_AS_CHARACTERISTICS.ID 
    WHERE DIM_AS_CHARACTERISTICS.TRANSACTION_INTRADAY_FLAG = 'N'
      AND DIM_AS_CHARACTERISTICS.BALANCE_CLOSING_FLAG = 'Y'
)
SELECT DD.WEEK_OF_YEAR, DD.CAL_YEAR, COALESCE(COUNT(DISTINCT FPP.ID),0) AS PAYMENTS, 
       COALESCE(COUNT(DISTINCT FAB.ACCOUNT_STATEMENT_ID),0) AS STATEMENTS
FROM FACT_PAY_PAYMENT FPP
  FULL OUTER JOIN FILTERED_BALANCES FAB ON FAB.BALANCE_DATE_ID = FPP.REQUESTED_EXECUTION_DATE_ID
  JOIN DIM_DATE DD ON FPP.REQUESTED_EXECUTION_DATE_ID = DD.ID OR FAB.BALANCE_DATE_ID = DD.ID 
GROUP BY DD.CAL_YEAR, DD.WEEK_OF_YEAR;

看看Oracles聚合函数:

https://docs.oracle.com/database/121/SQLRF/functions060.htm#SQLRF00633

也许这可以帮到你。

你无论如何都可以用subselect替换你的完整外连接,但我认为这并没有太大区别。