【问题标题】:Is this a Microsoft or an Oracle Problem?这是微软还是甲骨文的问题?
【发布时间】:2019-05-07 11:10:52
【问题描述】:

在我的原始线程中:How can I fix ORA: 01013 (user requested cancel...) when trying to link Oracle tables in MS Access? 我描述了一个试图将 Oracle 表链接到 Microsoft Access (office 365) 数据库的问题。输入 UID 和密码后进程超时。

在研究问题时,我能够确定 ODBC 驱动程序和 DSN 适用于 ADO、Toad 和 Microsoft Power BI(当对 Oracle 表使用特定查询时)。我无法从 Access 或 Excel 中记录 Oracle V$SQL 表中的条目以进一步解决问题。

但是,今晚,通过尝试通过 DSN 连接并浏览 Oracle 中的表,我能够让 Power BI 重新创建相同的行为。 Oracle 捕获了 SQL 调用,结果是这个 gem:

SELECT
    *
FROM
    (
        SELECT
            NULL table_qualifier,
            o1.owner         table_owner,
            o1.object_name   table_name,
            DECODE(o1.owner, 'SYS', DECODE(o1.object_type, 'TABLE', 'SYSTEM TABLE', 'VIEW', 'SYSTEM VIEW', o1.object_type), 'SYSTEM'
            , DECODE(o1.object_type, 'TABLE', 'SYSTEM TABLE', 'VIEW', 'SYSTEM VIEW', o1.object_type), o1.object_type) table_type,
            NULL remarks
        FROM
            all_objects o1
        WHERE
            o1.object_type IN ('TABLE',
                'VIEW'
            )
        UNION
        SELECT
            NULL table_qualifier,
            s.owner          table_owner,
            s.synonym_name   table_name,
            'SYNONYM' table_type, null remarks
        FROM
            all_objects    o3,
            all_synonyms   s
        WHERE
            o3.object_type IN (
                'TABLE',
                'VIEW'
            )
            AND s.table_owner = o3.owner
            AND s.table_name = o3.object_name
        UNION
        SELECT
            NULL table_qualifier,
            s1.owner          table_owner,
            s1.synonym_name   table_name,
            'SYNONYM' table_type,
            NULL remarks
        FROM
            all_synonyms s1
        WHERE
            s1.db_link IS NOT NULL
    ) tables
WHERE
    1 = 1
    AND ( table_type = 'TABLE'
          OR table_type = 'VIEW' )
ORDER BY
    4,
    2,
    3

我不知道从哪里开始这个查询。 union 语句中的第二个和第三个子查询被最后的 where 子句过滤掉了,所以没有用。第一个子查询试图从 all_objects 中检索表/模式列表。如果我将该 SQL 块限制为前 100,000 行并在 SQLPLUS 中运行,则在 Oracle 18c (XE) 中运行时间超过 20 分钟。我认为这是因为该对象在不断更新,即使查询正在运行。

Oracle 认证的 MS ODBC 规范的详细信息让我难以理解,所以我不知道是继续追究微软的票,还是将注意力转向 Oracle 作为问题的罪魁祸首。

任何和所有的建议表示赞赏。我真的需要知道哪一方负责上面的SQL。

谢谢!

【问题讨论】:

    标签: oracle odbc office365 dsn


    【解决方案1】:

    这看起来像是一个 Oracle 问题。尽管该错误是 ODBC 超时设置的直接结果,但该查询不应需要 20 分钟才能完成运行。

    遇到数据字典性能问题时,首先要尝试收集有关数据字典的统计信息。这为 Oracle 提供了有关对象大小的更多信息,因此它可以就如何连接表做出更好的决策。

    begin
        dbms_stats.gather_fixed_objects_stats;
        dbms_stats.gather_dictionary_stats;
    end;
    /
    

    如果这不起作用,您需要将查询缩小到可能仍然存在问题的最小大小。共有三个查询UNION ALL'd,很可能只有其中一个很慢。然后我们可以优化那个查询。

    (但是调整查询是一个需要多次来回进行的过程,并且很难通过 Internet 完成。您可能需要尝试寻找可以提供帮助的本地数据库管理员。因为您是使用 Express Edition,您无法联系 Oracle Support 寻求帮助。)

    【讨论】:

    • 谢谢,乔恩。我会试试看。查询中运行缓慢的部分是针对 all_objects 的子查询。没用的两个子查询及时执行。我的主要问题是为什么要使用 all_objects 而不是 all_tab_columns 来生成模式/表列表?这似乎是一种非常低效的方法,
    • @Arlie 我相信这个查询是为了返回所有“类似表格”的东西。可以从中选择的任何内容,例如表、视图或指向另一个表或视图的同义词。
    • 这是有道理的,尽管我幽默地注意到任何同义词最终都会被过滤掉。我确实尝试了您推荐的脚本,并通过禁用 DSN 上的超时属性让查询无限期运行。大约一个小时后它确实返回了结果。如果您有任何额外的数据库调优建议,或者建议阅读,我会全力以赴。
    • 在网上搜索后,我发现了其他关于在 Oracle 12c 和 18c 中访问 sys.all_objects 和 sys.all_synonyms 性能缓慢的报告。我在这里的实例中的行为确实很奇怪。查询 select count() from all_objects 需要 25 分钟才能运行。查询 select count() from all_objects where object_type='TABLE' 在 0.10 秒内运行。查询 select count(*) from all_objects where object_in ('TABLE','VIEW') 将我返回到 20 分钟 + 运行时领域。所以,我同意你的观点,这似乎确实是一个 Oracle 问题。
    【解决方案2】:

    如果我能够从 Power BI 更改 SQL 调用,我发现以下查询会产生相同的输出。它在安装了 Oracle 和 Power BI 的笔记本电脑上运行不到一秒。这与原始查询的近 30 分钟形成鲜明对比。 Microsoft,您可能想看看您的产品如何通过 DSN 连接到较新的 Oracle 产品:

    SELECT
        *
    FROM
        (
            SELECT
                NULL table_qualifier,
                o1.owner         table_owner,
                o1.object_name   table_name,
                o1.object_type table_type,
                NULL remarks
            FROM
                all_objects o1
            WHERE
                o1.object_type = 'TABLE' and
                o1.owner not in ('SYS','SYSTEM')
            UNION
            SELECT
                NULL table_qualifier,
                o1.owner         table_owner,
                o1.object_name   table_name,
                o1.object_type table_type,
                NULL remarks
            FROM
                all_objects o1
            WHERE
                o1.object_type = 'VIEW' and
                o1.owner not in ('SYS','SYSTEM')
        ) tables
    ORDER BY
        4,
        2,
        3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      • 2011-02-21
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 2015-01-18
      相关资源
      最近更新 更多