哪个select语句有更好的表现?

时间:2010-08-26 07:22:40

标签: sql performance oracle select

假设master_table包含许多记录,并且master_table,tableA,tableB,tableC和tableD的“id”字段在商业意义上都是相同的。

对于下面显示的2个选择语句,

他们都会返回相同的结果集吗?

哪一个会有更好的表现?

我认为如果tableA_tmp,tableB_tmp,tableC_tmp和tableD_tmp都返回较小的结果集,SQL1将比SQL2快,因为oracle不需要为每个master_table记录查询tableA_tmp,tableB_tmp,tableC_tmp和tableD_tmp一次。

但是如果tableA_tmp,tableB_tmp,tableC_tmp和tableD_tmp都返回大的结果集,SQL 2将会快得多,因为加入许多大结果集的成本远远高于查询tableA_tmp,tableB_tmp,tableC_tmp和tableD_tmp一次每个master_table记录。

如果我有任何误解,请纠正我。或建议的任何其他方法?

SQL1:

select 
        master_table.* ,
        tableA_tmp.cnt as tableA_cnt , 
        tableB_tmp.cnt as tableB_cnt ,  
        tableC_tmp.cnt as tableC_cnt ,  
        tableD_tmp.cnt as tableD_cnt 
    from
        master_table,
        (select  tableA.id as id, count(1) as cnt  from tableA group by tableA.id) tableA_tmp,
        (select  tableB.id as id, count(1) as cnt from tableB group by tableB.id) tableB_tmp,
        (select  tableC.id as id, count(1) as cnt from tableC group by tableC.id) tableC_tmp,
        (select  tableD.id as id, count(1) as cnt from tableD group by tableD.id) tableD_tmp
    where 
        master_table.id = tableA_tmp.id(+) and
        master_table.id = tableB_tmp.id(+) and
        master_table.id = tableC_tmp.id(+) and
        master_table.id = tableD_tmp.id(+) ;

SQL 2:

   select 
        master_table.* ,
        (select  count(*)  from tableA where tableA.id = master_table.id) as tableA_cnt,
        (select  count(*)  from tableB where tableB.id = master_table.id) as tableB_cnt,
        (select  count(*)  from tableC where tableC.id = master_table.id) as tableC_cnt,
        (select  count(*)  from tableD where tableD.id = master_table.id) as tableD_cnt
    from
        master_table;

5 个答案:

答案 0 :(得分:3)

查看执行计划

答案 1 :(得分:3)

连接通常比内联查询更好 - 对从主查询返回的每一行执行内联查询。

这意味着(1)优于(2)。至少在99%的情况下。

在少数情况下,定义数据和方式索引的分布可以在将查询执行时间倾向于2更高效时发挥作用,但这在普通数据库中很少发生。

答案 2 :(得分:1)

在较短的时间内开展工作的人。

答案 3 :(得分:0)

不同的结果集。 考虑TableA是否为空。

在语句1中,tableA_tmp也是空的。使用外连接时,将返回一行,但tableA_tmp.cnt的值将为null。

在语句2中,计数将被执行并返回零值。

两者的性能可能更好或更差,具体取决于卷,索引,scalar subquery caching,表聚类因子,内存....

答案 4 :(得分:0)

如果Master表和其他表足够大,SQL 1会更快。原因是表扫描。表扫描很昂贵,因为扫描涉及I / O.第一个查询只需要对表tableA,tableB,tablec和tableD中的每个表进行单次扫描。

在SQL2中,对于主表中的每个键,将对表tableA,tableB,tablec和tableD进行特殊扫描。如果主表有10行,表tableA将被扫描10次,tableB将被扫描10次,tableC将被扫描10次,依此类推。成本会很高。

示例将说明这一点。假设每个表都有1000条记录,每条记录都有不同的id。在第一个查询中,表tableA,tableB,tablec和tableD将被扫描一次,结果将被连接。生成的行数很大,但会在合理的时间内过滤。在SQL2中,每个表tableA,tableB,tablec和tableD将被扫描1000次。这是非常昂贵的。