sql - 强制 Oracle 在远程数据库站点上处理递归 CTE(可能使用 DRIVING_SITE 提示)

标签 sql oracle oracle11g recursive-query database-link

我正在尝试从远程表中获取数据。使用递归 CTE 从本地表中的种子数据集扩展数据。查询非常慢(300 个种子行到 800 个最终行需要 7 分钟)。
其他 "tiny local, huge remote" - 没有递归查询的情况 DRIVING_SITE提示效果很好。我还尝试将种子集从本地表导出到 remotedb 上的辅助表中。具有相同的结构并且 - 正在登录 remotedb - 作为纯本地查询运行查询( my_table 作为 pmy_table_seed_copy 作为 i )。花了 4 秒,这鼓励我相信强制查询到远程站点会使查询更快。
强制 Oracle 在远程站点上执行递归查询的正确方法是什么?

with s (id, data) as (
  select p.id, p.data
  from my_table@remotedb p
  where p.id in (select i.id from my_table i)
  union all
  select p.id, p.data
  from s
  join my_table@remotedb p on ...
)
select /*+DRIVING_SITE(p)*/ s.*
from s;
在上面的查询中,我试过
  • select /*+DRIVING_SITE(p)*/ s.*在主选择
  • select /*+DRIVING_SITE(s)*/ s.*在主选择
  • 省略 DRIVING_SITE全查询
  • select /*+DRIVING_SITE(x)*/ s.* from s, dual@remotedb x作为主选择
  • select /*+DRIVING_SITE(p)*/ p.id, p.data在第一个内部选择
  • select /*+DRIVING_SITE(p)*/ p.id, p.data在两个内部选择
  • select /*+DRIVING_SITE(p) MATERIALIZE*/ p.id, p.data在两个内部选择
  • (只是为了完整性 - 重写为 connect by 不适用于这种情况 - 实际上查询更复杂,并且使用无法由 connect by 表达的构造)

  • 都没有成功(即 7 分钟后返回数据)。

    最佳答案

    递归查询实际上执行广度优先搜索 - 种子行代表第 0 层,递归部分从第 (n-1) 层的元素中查找第 n 层的元素。原始查询旨在成为 merge ... using ... 的一部分条款。
    因此我将查询重写为 PLSQL 循环。每个循环生成一个级别。合并可防止插入重复项,因此最终不会添加新行并退出循环(构造传递闭包)。伪代码:

    loop
      merge into my_table using (
        select /*+DRIVING_SITE(r)*/ distinct r.* /*###BULKCOLLECT###*/
        from my_table          l
        join my_table@remotedb r on ...  -- same condition as s and p in original question are joined on
      ) ...
      exit when rows_inserted = 0;
    end loop;
    
    实际代码并不那么简单,因为 DRIVING_SITE实际上不直接与 merge 一起使用所以我们必须通过工作集合传输数据,但那是 different story .此外,插入行的计数不容易确定,它必须计算为合并前后行数之间的差异。
    解决方案并不理想。无论如何,它比递归 CTE(30 秒,13 个周期)快得多,因为可以证明查询正在使用 DRIVING_SITE暗示。
    如果有人找到答案如何使递归查询工作或证明它是不可能的,我会将问题悬而未决一段时间以等待。

    关于sql - 强制 Oracle 在远程数据库站点上处理递归 CTE(可能使用 DRIVING_SITE 提示),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66508812/

    相关文章:

    oracle - oracle 如何在内部存储带时区的时间戳

    image - 如何使用边界分割具有多部分/相关MIME类型的电子邮件?

    甲骨文 - ORA-06502 : PL/SQL: numeric or value error (DBMS_OUTPUT)

    Oracle - 特定用户的审计跟踪

    sql - SSIS:如何将 SQL 语句从文件中提取到字符串变量中?

    sql - CrateDB 聚合所有数组元素

    mysql - 使用 SQL Developer 3 将 MySQL 数据库迁移到 Oracle 11g

    sql - 在 PL/SQL 中未使用游标进行更新

    C# Linq to SQL 无效转换异常

    php - 无法添加或更新子行 : a foreign key constraint fails on real server