VS过分割的比较组

时间:2012-02-17 12:31:13

标签: sql oracle database-performance

假设一个表CAR有两列CAR_ID (int)VERSION (int)

我想检索每辆车的最高版本。

所以有两种解决方案(至少):

select car_id, max(version) as max_version 
  from car  
 group by car_id;

或者:

select car_id, max_version 
  from  ( select car_id, version
               , max(version) over (partition by car_id) as max_version
            from car
                ) max_ver  
 where max_ver.version = max_ver.max_version

这两个查询的表现是否相似?

3 个答案:

答案 0 :(得分:3)

我知道这是非常古老但我们应该指出。

select car_id, max_version 
  from (select car_id
             , version
             , max(version) over (partition by car_id) as max_version
          from car ) max_ver  
 where max_ver.version = max_ver.max_version

不确定为什么你做了那样的选项二......在这种情况下,子选择在理论上应该更慢,因为你从同一个表中选择2x然后将结果加回到自身。

只需从内联视图中删除版本,它们就是一样的。

select car_id, max(version) over (partition by car_id) as max_version
  from car

在这种情况下,性能实际上取决于优化器,但是原来的答案显示内联视图,因为它们会缩小结果。虽然这不是一个很好的例子,因为它的相同表格在给定的选择中没有过滤器。

当您选择许多列但需要适合结果集的不同聚合时,分区也很有用。否则,您被迫按其他列分组。

答案 1 :(得分:2)

是可能会影响

第二个查询是内联视图的示例。 这是一种非常有用的方法,可以使用各种类型的计数或使用任何聚合函数来执行报告。

Oracle执行子查询,然后将结果行用作FROM子句中的视图。

在我们考虑性能时,始终建议使用内联视图,而不是选择其他子查询类型。

还有一个问题是第二个查询会给出所有最大记录,而第一个查询只会给你一个最大记录。

see here

答案 2 :(得分:2)

这取决于您的索引方案和表中的数据量。优化器可能会根据表中实际存在的数据做出不同的决策。

我发现,至少在SQL Server中(我知道你问过Oracle)优化器更有可能使用PARTITION BY查询和GROUP BY查询执行完整扫描。但这只是在你有一个包含CAR_ID和VERSION(DESC)的索引的情况下。

故事的寓意是我会彻底测试选择正确的故事。对于小桌子,没关系。对于真正的,非常大的数据集,两者都不会很快......