有时,Oracle似乎更喜欢MERGE JOIN CARTESIAN
操作而不是常规MERGE JOIN
。知道数据并查看具体的执行计划,我可以看到这个操作通常不是问题,因为其中一个连接的实体只能在手头的查询中返回一个记录。
然而,由于历史原因,我们的DBA对笛卡尔产品普遍不满意。
所以我想更好地分析这些案例,并在我的论证中备份文档。是否有任何关于查询转换的官方Oracle文档和CBO,我可以在其中了解Oracle更喜欢MERGE JOIN CARTESIAN
(或类似)操作的情况?
在这种情况下,我正在使用Oracle 11g(11.2.0.2.0)
更新:
这些是类似的问题,但他们没有解释为什么或当 Oracle更喜欢MJC
而不是常规MERGE JOIN
时 p>
答案 0 :(得分:6)
是的,提及笛卡尔联合通常会让DBA的心脏跳过一个节拍。由缺少连接条件引起的笛卡尔连接肯定是一个难以处理的问题 - 这些连接类型可以“炸毁”临时空间并导致所有类型的警报消失。
我在Oracle的官方11g文档中没有找到关于这个特定连接方法的任何内容,但我确实在他们的支持DB中找到了大量关于它的问题的文章。在过去的几周里,我已经把它们中的一些追了下来,这就是我找到的。
MJC的来源是CBO优化。当加入的结果集的基数很低时,MJC是一种非常有效的优化。当优化程序未正确估计作为连接输入的一个或多个结果集的基数时,会出现此问题。如果估计的行= 1(或者是低数字)但结果集的实际行很大,则优化器仍然可以选择MJC,从而产生次优计划。这是轻描淡写的。我遇到了这种情况的问题,查询运行了几天而没有完成。让CBO回到正轨后,它们可以在几秒钟而不是几小时或几天内运行。
查看此Estimated Rows与Actual Rows的最佳方法是运行查询并查看其执行计划统计信息。您提到您使用的是11g - 使用SQL监控功能。此功能的输出将显示执行计划的每个步骤花费了多少时间。它还会显示Estimated Rows vs Actual rows。您正在寻找MJC输入的估计行数与实际行数的巨大差异。
SQL Monitoring可通过OEM / DB Control获得,或者您可以使用API(搜索DBMS_SQLTUNE.REPORT_SQL_MONITOR)。可以使用带有查询的GATHER_PLAN_STATISTICS提示收集相同类型的信息,然后使用DBMS_XPLAN生成报告...详细信息为here。
那么如何摆脱它呢?尝试解决对象统计问题。一旦CBO知道它真的处理数百,数千或数百万条记录作为连接的输入而不是“1”,它应该选择更适合数据集的连接方法而不选择MJC。说起来容易做起,关于这个主题的书籍已经写好了,但至少要查看基础知识 - 确保查询中涉及的所有表至少都有统计信息。如果您在where子句中应用了多列表达式,则也可以利用补充统计信息。
如果你需要一个大锤子,有一些隐藏的参数允许/不允许使用MJC。它们可以在数据库级别,会话级别或查询级别(使用提示)实现。我将参数名称留作读者的练习,因为Oracle的官方立场是它们只应在支持的指导下使用。不要告诉他们,但是在尝试使对象统计信息合作失败之后,我已经在查询级别上使用OPT_PARAM提示消除了MJC。