查找时间的比较:外键是否存在

时间:2012-09-12 17:40:23

标签: database performance oracle join

一位同事最近向我描述了重建数据库的计划。新数据库将符合简单的star schema:父表将包含密钥和一些上下文信息,该密钥将用作其他表中的外键字段。外键字段可能多次出现在同一子表中。

伪代码:

TABLE Parent
   INT key PRIMARY_KEY
   INT foo
   ...

TABLE Child1
   INT key FOREIGN_KEY REFERENCES Parent.key
   BLOB bar
   ...

TABLE Child2
   INT key FOREIGN_KEY REFERENCES Parent.key 
   VARCHAR tar
   ...

设计背后的动机是简化ParentChild<n>之间的JOIN,这与之前的架构相比很复杂。

为了进一步加快JOIN,我的同事希望尽量减少使用OUTER JOIN。具体来说,她希望通过使用JOINS并以特定方式维护子表中的数据来模拟OUTER JOIN:填充所有这些,以便key中的每个Parent至少有一个Child<n>key中使用null值的行,即使该行已满Parent秒。这样,在Child<n>上的keykey之间执行的任何JOIN都会为Parent中的每个key返回至少一个结果,更像是一个OUTER JOIN。 / p>

抛开以这种方式维护数据是否值得努力的问题,假设所有null字段都被正确编入索引并且大约有一半的子行,则这种方法比执行OUTER JOINS更有效。被{{1}}排除了吗?

问题似乎归结为“对索引中存在的值而不是不存在的值进行索引查找会更快吗?”假设索引的操作类似于B树或哈希,答案就像“不”,但我不知道是否足够确定。

2 个答案:

答案 0 :(得分:2)

就个人而言,我没有注意到外连接和内连接之间的主要性能差异。为什么你的同事认为他们比较慢?

添加其他记录会对性能产生两种影响。原始数据变大,需要更多页面来存储数据。这会对性能产生很大影响,特别是如果其他页面(没有有用数据)与更有用的结构竞争空间(比如索引)。

第二个影响是指数。它需要更大,这可能会导致更深的索引和更多的索引页。这两者都会对性能产生影响。

还有另一个问题,与性能无关。编写查询的用户/开发人员需要完全理解存在这些空记录。执行COUNT(*)或COUNT()非常容易,并期望结果准确反映包含数据的记录数。如果不是这种情况,可能会导致编码问题。

答案 1 :(得分:1)

我认为这种方法不会提高性能。

内部联接 通常比外部联接更快。这是因为内部联接更具限制性,为优化器提供了更多机会来减少计划中早期的结果集。

但是如果你人为地添加数据,你的内部联接就不再具有更多的限制性了。