0

我不确定我是否正确命名了这个问题,但解释可能有助于向您解释我的问题。

我有一个主表,说 PROJ_MASTER 包含数百万条记录。它包含具有映射到其他表以获取这些代码详细信息的代码的列,例如 PROJ_SUB_1 和 PROJ_SUB_2。

在主表上编写查询的最佳方法是什么 1)映射列


SELECT PM.SOME_COL_1,
       PM1.COL1,
       PM1.COL2
  FROM PROJ_MASTER PM, PROJ_SUB_1 PS1, PROJ_SUB_2 PS2
 WHERE PM1.COL1 = PS1.COL1
   AND PM1.COL2 = PS2.COL2

2)或使用嵌套查询


SELECT PM.SOME_COL_1,
       (SELECT DISTINCT PM1.COL1
         FROM PROJ_SUB_1 PS1
       WHERE PM.COL1 = PS1.COL1) AS COL1
       (SELECT DISTINCT PM1.COL2
         FROM PROJ_SUB_2 PS2
       WHERE PM.COL2 = PS2.COL2) AS COL2
  FROM PROJ_MASTER PM

我在使用别名时犯了一些错误(PM1 和 PM2 而不是 PM)。

我正在显示查询计划第一个查询)


SELECT STATEMENT, GOAL = ALL_ROWS   Cost=23827  Cardinality=1037978 Bytes=76810372
 HASH UNIQUE                Cost=23827  Cardinality=1037978 Bytes=76810372
  HASH JOIN             Cost=5638   Cardinality=1037978 Bytes=76810372
   TABLE ACCESS FULL    Object owner=USER   Object name=PROJ_MASTER 
                                    Cost=5  Cardinality=557         Bytes=17267
   HASH JOIN                Cost=5619   Cardinality=872654  Bytes=37524122
    TABLE ACCESS FULL   Object owner=USER   Object name=PROJ_SUB_1
Cost=28 Cardinality=9827 Bytes=294810 TABLE ACCESS FULL Object owner=USER Object name=PROJ_SUB_2
Cost=5579 Cardinality=872654 Bytes=11344502

第二次查询)


SELECT STATEMENT, GOAL = ALL_ROWS     Cost=9810 Cardinality=872654  Bytes=11344502
 TABLE ACCESS FULL  Object owner=USER   Object name=PROJ_SUB_1
Cost=5 Cardinality=1 Bytes=31 TABLE ACCESS FULL Object owner=USER Object name=PROJ_SUB_2
Cost=28 Cardinality=1 Bytes=30 HASH UNIQUE Cost=9810 Cardinality=872654 Bytes=11344502 TABLE ACCESS FULL Object owner=USER Object name=PROJ_MASTER Cost=5579 Cardinality=872654 Bytes=11344502
提前致谢。

4

2 回答 2

2

第一种方法是最好的,原因有很多。它更易于阅读和理解。根据功能和性能,第一个也更好。在大量数据中,您可以填补差异。这是我的经验。

于 2012-12-06T07:16:16.093 回答
1

像 Oracle 这样的数据库就是为了加入而诞生的。你的第一个查询是做你想做的事情的“正常”方式,而且会很快。

说了这么多,有几点:

大多数人更喜欢 ANSI 连接语法,因此这将更容易阅读:

SELECT PM.SOME_COL_1,
       COL1,
       COL2
  FROM PROJ_MASTER PM 
       JOIN PROJ_SUB_1 USING (COL1) 
       JOIN PROJ_SUB_2 USING (COL2)

当然,您可能会包含来自PROJ_SUB_1和的一些列PROJ_SUB_2

第二个查询同样可能应该从SUB表中选择一些东西,否则这将毫无意义,但我假设这是一个错字。在这种情况下,功能上的区别在于:

  • 如果有多个匹配行,查询将失败(但从问题来看,假设表之间存在 FK 关系似乎很自然)
  • 这个查询通常比第一个查询更冗长、更慢、可读性更差,但它有一个特殊的属性:你可以一眼看出,如果查询成功,每行将返回一行,而无需知道PROJ_SUB_2查找键和关系。

最后,DISTINCT如果确实存在强制执行的 FK/PK 关系,则 是多余的。

于 2012-12-06T08:00:41.253 回答