Oracle,使用子选择时性能下降

时间:2010-06-02 12:28:02

标签: performance oracle

如果您获取所有行,我的视图会非常慢。但是如果我选择一个子集(在where子句中提供ID),性能非常好。我无法对ID进行硬编码,因此我创建了一个子选择来从另一个表中获取ID。子选择仅返回一个ID。现在性能非常慢,似乎Oracle在使用where子句之前正在评估整个视图。我可以以某种方式帮助Oracle,以便SQL 2和3具有相同的性能吗?我正在使用Oracle 10g

1慢

从ci.my_slow_view

中选择*

2快

从ci.my_slow_view中选择*,其中id = 1;

3慢

从ci.my_slow_view中选择*,其中id为(从active_ids中选择id)

4 个答案:

答案 0 :(得分:2)

这是预期的行为...... 3很慢,因为Oracle将执行“全表扫描”,这意味着你的索引没有帮助(你的where子句不包含任何常量或范围,并且是无界的,这意味着无论你使用什么索引,所有的行都是可能是加入条件的候选人。

可能的改进: 首先,检查join / pk列上的索引是否正常(my_slow_view和active_ids中的id)。这是第二步所必需的: 其次,为您的表和视图生成表统计信息,这将使Oracle高速缓存内存优化器启动。 (它应该可以工作,因为假设你的active_ids表足够小,可以完全在内存中。)

第二种方法: 在PL / SQL中编写存储过程,其中id是in参数,并重写SQL,以便使用绑定参数。

这应该为您提供所需的灵活性(没有硬编码ID),以及最快查询的速度。

答案 1 :(得分:2)

怎么样

select * from ci.my_slow_view where id = (select id from active_ids)

将“in”替换为“=”将告诉Oracle您希望“select id from active_ids”只返回一行。

答案 2 :(得分:0)

  

我无法对ID进行硬编码,因此我创建了一个   sub select从另一个获取ID   表。子选择仅返回一个   ID。

最有可能的是,收集小表上的统计信息(虽然它包含一行)会有所帮助,因为这样可以帮助Oracle意识到它很小并鼓励它使用ID上的索引。

然而,听起来这确实不是解决原始问题的正确方法。通常,当想要使用不同的查找值重复执行查询时,最好的方法是使用绑定变量。在SQLPlus中执行此操作的基本方法是:

SQL>  variable id number
SQL>  exec :id := 1;
SQL>  select * from ci.my_slow_view where id = :id ;
SQL>  exec :id := 2;
SQL>  select * from ci.my_slow_view where id = :id ;

实现这一点的细节取决于您正在开发的环境。

答案 3 :(得分:0)

或者:

select * from ci.my_slow_view, active_ids
where my_slow_view.id = active_ids.id;