6

有时,Oracle 似乎更喜欢MERGE JOIN CARTESIAN操作而不是常规的MERGE JOIN. 了解数据并查看具体的执行计划后,我可以看到此操作通常不是问题,因为其中一个连接实体只能返回手头查询中的一条记录。

但是,由于历史原因,我们的 DBA 普遍不喜欢笛卡尔积。

所以我想更好地分析这些案例,并在我的论证中得到文件的支持。是否有任何关于查询转换和 CBO 的官方 Oracle 文档,我可以在其中了解 Oracle 更喜欢MERGE JOIN CARTESIAN(或类似)操作的情况?

在这种情况下,我使用的是 Oracle 11g (11.2.0.2.0)

更新

这些是类似的问题,但它们没有解释为什么何时Oracle 更喜欢MJC常规的MERGE JOIN

4

1 回答 1

6

是的,提到笛卡尔连接通常会让 DBA 心跳加速。由缺少连接条件引起的笛卡尔连接绝对是一个痛苦的处理 - 这些连接类型可以“炸毁”临时空间并导致所有类型的警报响起。

我在 Oracle 的 11g 官方文档中没有找到任何关于这种特定连接方法的内容,但我确实在他们的支持数据库中找到了很多关于它的问题的文章。在过去的几周里,我已经追查了其中的一些,这就是我发现的。

MJC 的来源是 CBO 优化。MJC 是一种优化,当连接的结果集的基数较低时效果很好。当优化器未正确估计作为连接输入的一个或多个结果集的基数时,就会出现此问题。如果估计的行数 = 1(或者是一个小数字)但结果集的实际行数很大,那么优化器可能仍会选择 MJC,从而导致次优计划。这是一种轻描淡写的说法。我遇到了这种情况的问题,并且查询运行了好几天但没有完成。在让 CBO 重回正轨后,他们在几秒钟内而不是几小时或几天内运行。

找出这个 Estimated Rows vs Actual Rows 是否是这种情况的最佳方法是运行查询并查看其执行计划统计信息。您提到您使用的是 11g - 使用 SQL 监控功能。此功能的输出将显示您在执行计划的每个步骤上花费了多少时间。它还将向您显示估计行与实际行。您正在寻找 MJC 输入的估计行与实际行之间的巨大差异。

SQL 监控可通过 OEM/DB Control 获得,或者您可以使用 API(搜索 DBMS_SQLTUNE.REPORT_SQL_MONITOR)。可以使用带有查询的 GATHER_PLAN_STATISTICS 提示收集相同类型的信息,然后使用 DBMS_XPLAN 生成报告...详细信息在这里

那么如何摆脱它呢?尝试解决对象统计问题。一旦 CBO 知道它确实在处理数百、数千或数百万条记录作为连接的输入而不是“1”,它应该选择更适合数据集的连接方法,而不是选择 MJC。说起来容易做起来难,已经写了关于这个主题的书籍,但至少要检查一下基础知识——确保查询中涉及的所有表至少都有统计信息。如果您在 where 子句中应用了多列表达式,也可以利用补充统计信息。

如果你需要一把大锤子,有一些隐藏参数允许/禁止使用 MJC。它们可以在数据库级别、会话级别或查询级别(使用提示)实现。我将把参数名称留给读者作为练习,因为 Oracle 的官方立场是它们只能在支持的指导下使用。不要告诉他们,但在尝试让对象统计信息合作失败后,我在查询级别使用 OPT_PARAM 提示消除了 MJC 取得了一些成功。

于 2011-11-16T19:46:21.767 回答