1
3
|
2
2
Oracle的optimizer没有对平等性做出可传递的假设。虽然我们知道如果A=B和A=C,那么B=C,Oracle并不认为B和C之间存在关系;C除非WHERE条款或连接条件中明确规定。 我假设您对A、B和/或C有其他约束(而不是只选择表的全部内容-否则您的I/O不会太低,除非您的表很小,在这一点上优化是没有意义的)。因此,对A、B&的限制确实更多;C比你指定的要多。Oracle的优化器将查看FROM子句中的所有表,在WHERE子句中列出针对这些表的约束,然后根据这些表的索引确定约束的选择性。然后,它将检查各种攻击计划的排列,并确定哪种计划产生的希望最大(这些是您在计划中看到的基数值)。如果没有B=C条件,它将排除从B开始到C的计划(反之亦然),这些可能是最好的计划。 |
3
2
你有两个问题。 首先,使用原始SQL,优化器估计A中与B中的ID匹配的行数,而B中也有与C中的行匹配的行数。该估计不准确,并且选择了错误的计划。 现在,添加冗余条件。Oracle假定没有任何条件是真正冗余的(如果它们是冗余的,智能开发人员就不会包含它们)。它还假设每个条件独立于其他条件。例如,一个select where hair='BLAD'可能获得表格的10%,一个select where SEQUENCE='F'可能获得表格的50%。甲骨文会假设,如果选择头发=‘秃头’和性别=‘F’,则会给出5%(而事实上,秃头主要限于男性)。 通过添加“冗余”谓词,Oracle将高估要排除的数量或行,并相应地选择计划。 如果使用冗余谓词,Oracle选择了更好的计划,则表明原始查询的估计值高估了匹配的行数。冗余谓词是用低估来对抗这一点。在这种情况下,两个错误就是一个正确。
另外,我假设所有ID的数据类型都是一致的。如果B.ID和C.ID是日期,A.ID是字符,反之亦然,则可能有一些行,其中A.ID=B.ID和A.ID=C.ID,但B.ID!=C.ID,因为隐式转换可能会丢失时间戳。 |
4
1
这两个问题在我看来根本不一样。
因为当你这样做的时候,B和C都有A的外键
唯一地 如第一个查询中所示,创建表A。 在第二个查询中,通过将表C连接到更小的数据集(即A和B的交集),对问题进行了优化, 和 较小的数据集,即A和C的交集。 |
maddy · 如何根据oracle SQL中的某一列值进行排名 1 年前 |
kiric8494 · 显示以元音开头和结尾的城市名称 2 年前 |
Franz Biberkopf · Oracle:组合子查询和聚合函数 2 年前 |
BitLauncher · 甲骨文-如何模拟位列和布尔和/或? 2 年前 |
Arifullah · 如何从oracle中的列中删除特定的初始字符? 2 年前 |
Anar · Oracle SQL用户定义函数 2 年前 |
user1312312 · 如何为一组表编写通用触发器? 2 年前 |