Sql 优化完全外部联接查询
下面的外部连接查询需要10分钟以上才能生成结果,如何进一步优化,有没有办法避免完全外部连接 任何帮助都将不胜感激 谢谢Sql 优化完全外部联接查询,sql,oracle,optimization,Sql,Oracle,Optimization,下面的外部连接查询需要10分钟以上才能生成结果,如何进一步优化,有没有办法避免完全外部连接 任何帮助都将不胜感激 谢谢 WITH CMD_DEP AS ( SELECT DEPLOYMENT_ID FROM CMD_DEPLOYMENT WHERE ORG_ID = 'xyz' AND DEPLOYMENT_DATE BETWEEN TIMESTAMP '2013-02-11 13:03:36.928000' AND TIMESTAMP '2020-02-
WITH CMD_DEP AS (
SELECT
DEPLOYMENT_ID
FROM
CMD_DEPLOYMENT
WHERE
ORG_ID = 'xyz'
AND DEPLOYMENT_DATE BETWEEN TIMESTAMP '2013-02-11 13:03:36.928000' AND TIMESTAMP '2020-02-11 13:03:36.928000'
AND TYPE NOT IN ('PROOF',
'TEST') )
SELECT
COALESCE(opens.UA_DEVICE,
clicks.UA_DEVICE) deviceType,
COALESCE(opens.OPENS,
0) opens,
COALESCE(clicks.CLICKS,
0) clicks
FROM
(
SELECT
o.UA_DEVICE,
SUM(o.HTTP_OPEN_CNT) OPENS
FROM
AGG_DPLYMNT_OPEN_DEVICE_TOTALS o,
CMD_DEP cmd_dep
WHERE
cmd_dep.DEPLOYMENT_ID = o.DEPLOYMENT_ID
GROUP BY
o.UA_DEVICE) opens
FULL OUTER JOIN (
SELECT
c.UA_DEVICE,
SUM(c.HTTP_REDIRECT_CNT) CLICKS
FROM
AGG_DPLYMNT_CLICK_DEVICE_TOTAL c,
CMD_DEP cmd_dep
WHERE
cmd_dep.DEPLOYMENT_ID = c.DEPLOYMENT_ID
GROUP BY
c.UA_DEVICE) clicks ON
opens.UA_DEVICE = clicks.UA_DEVICE;
改变这个
SELECT
COALESCE(opens.UA_DEVICE,
clicks.UA_DEVICE) deviceType,
COALESCE(opens.OPENS,
到
然后运行SQL。完成后,运行以下操作:
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'))
你会得到一份计划报告加上实际值,而不是估计值加上时间。这为了解问题所在提供了一个很好的起点,或者您可以将其发回此处寻求帮助查询看起来不错(尽管有1890年代的加入)。因此,您可以使用索引来加快访问速度。查看的行受cmd\u部署
上的条件限制。因此,从这个索引开始:
create index idx1 on cmd_deployment(org_id, deployment_date, type, deployment_id);
这假设org\u id
是这里的最大限制因素。它也可能是部署日期,在这种情况下,您应该先创建此列。或者只需创建两个索引,然后查看使用了哪一个
create index idx1b on cmd_deployment(deployment_date, org_id, type, deployment_id);
从那里你可以通过
create index idx2 on agg_dplymnt_open_device_totals(deployment_id, ua_device, http_open_cnt);
create index idx3 on agg_dplymnt_click_device_total(deployment_id, ua_device, http_redirect_cnt);
至于您的查询,您可以通过具体化查询的特殊视图来加快速度:
WITH CMD_DEP AS (
SELECT /*+MATERIALIZE*/
DEPLOYMENT_ID
以优化查询。请找到以下步骤
使用union all而不是外部联接
WITH CMD_DEP AS (
SELECT
DEPLOYMENT_ID
FROM
CMD_DEPLOYMENT
WHERE
ORG_ID = '05321f3b-5937-4394-8d10-0eb91ae76562'
AND DEPLOYMENT_DATE BETWEEN TIMESTAMP '2013-02-11 13:03:36.928000' AND TIMESTAMP '2020-02-11 13:03:36.928000'
AND TYPE NOT IN ('PROOF',
'TEST') )
SELECT
UA_DEVICE deviceType ,
sum(OPENS) opens ,
sum(CLICKS) clicks
FROM
(
SELECT
UA_DEVICE,
HTTP_OPEN_CNT AS opens,
0 AS clicks
FROM
AGG_DPLYMNT_OPEN_DEVICE_TOTALS c,
CMD_DEP cmd_dep
WHERE
cmd_dep.DEPLOYMENT_ID = c.DEPLOYMENT_ID
UNION ALL
SELECT
UA_DEVICE,
0 ,
HTTP_REDIRECT_CNT
FROM
AGG_DPLYMNT_CLICK_DEVICE_TOTAL o,
CMD_DEP cmd_dep
WHERE
cmd_dep.DEPLOYMENT_ID = o.DEPLOYMENT_ID )
GROUP BY
UA_DEVICE ;
为什么要将古老的基于逗号的连接与正确、标准的
JOIN
语法混为一谈?可能不需要外部联接。您应该提供示例数据、所需结果和所需逻辑的解释。运行解释计划并发布results@OldProgrammer如何运行?SQL_ID 5rsm4y10jd4p2,子编号0开始DBMS_输出。获取_行(:1,:2);结束;注意:无法获取SQL\u ID:5rsm4y10jd4p2的计划,子\u编号:0请验证SQL\u ID和子\u编号的值;也可能是计划不再在游标缓存中(检查v$sql\u计划),因为您打开了serverout输出,所以我们选择了它。您需要在服务器输出关闭的情况下再次执行此操作如何关闭?设置服务器输出关闭我不确定您从何处获得这些想法,也不确定您在哪个平台上进行测试。你没有提供任何理由说明为什么你应该避免这些方法,或者为你的推理提供来源。而你错了。数据库优化器(不管你使用的是什么数据库)不能总是正确地优化这样的查询(使用子查询)。在这种情况下,优化器的问题是选择连接结果集的正确方式。有几种连接两个结果集的算法。算法的选择取决于一个和另一个结果集中包含的记录数。如果连接两个物理表(子查询不是物理表),数据库可以通过可用的统计信息轻松确定两个结果集中的数据量。嗨,Sanjay。你说了三点。这是一个特定于Oracle的问题。如果Oracle未能正确优化子查询,则可能是因为缺少统计数据或Optimizer存在错误。第一个可以管理,第二个需要使用用例创建SR并修复。子查询可以使代码更清晰,在某些情况下会导致计划优化。不应该仅仅因为了解它们的用途和好处就避免它们。您还建议避免使用CTE。为什么?你在第三条中的建议完全是错误的。
WITH CMD_DEP AS (
SELECT
DEPLOYMENT_ID
FROM
CMD_DEPLOYMENT
WHERE
ORG_ID = '05321f3b-5937-4394-8d10-0eb91ae76562'
AND DEPLOYMENT_DATE BETWEEN TIMESTAMP '2013-02-11 13:03:36.928000' AND TIMESTAMP '2020-02-11 13:03:36.928000'
AND TYPE NOT IN ('PROOF',
'TEST') )
SELECT
UA_DEVICE deviceType ,
sum(OPENS) opens ,
sum(CLICKS) clicks
FROM
(
SELECT
UA_DEVICE,
HTTP_OPEN_CNT AS opens,
0 AS clicks
FROM
AGG_DPLYMNT_OPEN_DEVICE_TOTALS c,
CMD_DEP cmd_dep
WHERE
cmd_dep.DEPLOYMENT_ID = c.DEPLOYMENT_ID
UNION ALL
SELECT
UA_DEVICE,
0 ,
HTTP_REDIRECT_CNT
FROM
AGG_DPLYMNT_CLICK_DEVICE_TOTAL o,
CMD_DEP cmd_dep
WHERE
cmd_dep.DEPLOYMENT_ID = o.DEPLOYMENT_ID )
GROUP BY
UA_DEVICE ;