我使用以下查询来查看我的所有对帐单和付款的概述,按年份分组:
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;
这给出了以下输出:
这样可行,但由于我在查询中使用完全外连接,因此性能严重泄漏。您可以在下面找到Oracle SQL开发人员的解释计划:
问题是降低此查询的成本。我试图拆分付款和报表,但我有一个逻辑问题。当我在一周内付款但没有发言时,报表结果表没有一周没有发表声明的条目。
如何以更好的性能解决此问题?
答案 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替换你的完整外连接,但我认为这并没有太大区别。