Oracle 10g 64位 红帽企业Linux 5 64位
我目前可以访问规范化的第三方数据库。它们拥有大量数据,我的要求是通过连接大量表来公开物化VIEW。
表1:Example_Master 列:MasterID(VARCHAR2(250))MasterName(VARCHAR2(250)) 行数:9000万 主键:MasterID
表2:Example_ChildA1 列:ChildA1ID(VARCHAR2(250))MasterID(VARCHAR2(250)) 行数:2500万
表3:Example_ChildA1ID 列:ChildA1ID(VARCHAR2(250))ChildA1Name(VARCHAR2(250)) 主键:ChildA1ID
表4:Example_ChildA2 列:ChildA2ID(VARCHAR2(250))MasterID(VARCHAR2(250)) 行数:3500万
表5:Example_ChildA2ID 列:ChildA2ID(VARCHAR2(250))ChildA2Name(VARCHAR2(250)) 主键:ChildA2ID
等,
每个子表可能有也可能没有等同于MASTERID的条目。所以我必须获得所有MASTERID及其相关的CHILD名称。如果没有任何Child的等效值,那么它必须返回'NULL'。所以我现在已经在Materialized VIEW语法下面了
SELECT a.MasterName, c.ChildA1Name, e.ChildA2Name, g.ChildA3Name
FROM
Example_Master a,
Example_ChildA1 b,
Example_ChildA1ID c,
Example_ChildA2 d,
Example_ChildA2ID e,
Example_ChildA3 f,
Example_ChildA3ID g
WHERE
c.ChildA1ID(+) = b.ChildA1ID
AND e.ChildA2ID(+) = d.ChildA2ID
AND g.ChildA3ID(+) = f.ChildA3ID
AND a.MasterID=b.MasterID (+)
AND a.MasterID=d.MasterID (+)
AND a.MasterID=f.MasterID (+)
我必须加入另外5个像上面这样的子表,并且这个查询的成本已经变得如此巨大,以至于需要将近16分钟来获得结果。有没有更好的方法来使用OUTER JOINS?如果您需要有关我的问题的更多详细信息,请告诉我。
谢谢!
答案 0 :(得分:5)
当您平等加入这样的大表时,您可以希望的最佳计划是一组散列外连接,其成本通常等于全表扫描的成本加上溢出的大型散列表的开销磁盘。
如果有覆盖索引,则只能真正降低全表扫描的成本。
散列表溢出到磁盘的可能性当然可以通过提供大量可用内存来减少,但也可以通过对连接键上的表进行等分来帮助。通常,这是通过散列分区完成的,使用尽可能多的散列分区来防止将哈希表保留在内存中。更多来自文档:https://docs.oracle.com/cd/B28359_01/server.111/b32024/part_avail.htm#CIHCDBIF(或搜索“分区智能连接”)
请注意,您不需要使用并行查询来从分区连接中受益 - 串行查询也会带来好处。
顺便说一句,不要感谢你没有使用低于10g的版本 - 你无法有效地与LARGE_TABLE LEFT OUTER JOIN SMALL TABLE等同连接,因为优化器无法首先访问小型表来创建哈希表 - 这将始终是一个嵌套循环:(