Oracle:使用嵌套查询与使用映射

时间:2012-12-06 07:06:34

标签: sql oracle

我不确定我是否已将此问题命名为正确,但解释可能有助于向您解释我的问题。

我有一张主表,说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
在此先感谢。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

像甲骨文这样的数据库诞生了。您的第一个查询是'正常'如何做你想做的事情,并且会很快。

话虽如此,有几点:

Most people prefer ANSI join syntax,所以这将更容易阅读:

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_1PROJ_SUB_2中添加一些列。

第二个查询同样可能应该从SUB表中选择一些内容,否则它将毫无意义,但我认为这是一个错字。在这种情况下,功能差异是:

  • 如果有多个匹配的行,则查询将失败(但从问题看起来很自然地假设表之间存在FK关系)
  • 这个查询通常比第一个查询更冗长,更慢,更不易读,但它有一个特殊属性:您可以一眼看出完全将为{}中的每一行返回行{1}}如果查询成功,则不知道查找键和关系。

最后,如果确实存在FK / PK关系,则PROJ_SUB_2是多余的。