Sql 优化完全外部联接查询

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-

下面的外部连接查询需要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-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

以优化查询。请找到以下步骤

  • 避免使用CTE
  • 避免使用子查询,而是使用表变量获取所需的数据
  • 检查是否可以对整型列而不是VARCHAR列应用WHERE条件

  • 使用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 ;