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

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

问题描述:

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

1缓慢

SELECT * FROM ci.my_slow_view

2快速

SELECT * FROM ci.my_slow_view其中id = 1;

3慢

SELECT * FROM ci.my_slow_view其中id中(选择active_ids ID)

+0

尝试写一个简单的程序来选择视图。 – 2013-07-29 14:31:33

这是预期的行为... 3是缓慢的,因为甲骨文将执行“全表扫描“,这意味着你的索引没有帮助那里(你的where子句不包含任何常量或范围,并且是*的,这意味着无论使用哪个索引,所有行都有可能成为连接条件的候选对象)

可能的即兴表演t: 首先,检查您的join/pk列(my_slow_view和active_ids中的id)索引是否正确。这是第二步所必需的: 其次,为你的表和视图生成表格统计信息,这将使Oracle缓存内存优化器开始工作。 (它应该工作,因为它假定你的active_ids表足够小,在内存中。)

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

这应该给你你需要的灵活性(没有硬编码ID)和最快的查询速度。

+0

谢谢,这样做! exec dbms_stats.gather_table_stats('***','***',cascade => TRUE); – Wyass 2010-06-03 07:09:32

我不能硬编码的ID,所以我创建 子选择获得从另一个 表中的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 ; 

执行此操作的详细信息取决于您正在开发的环境。

+0

由于一些设计决定,我不得不用查询创建一个视图,所以一个过程将不起作用。 select * from ci.my_slow_view where id in(select id from active_ids) – Wyass 2010-06-02 14:20:37

如何

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

更换“中的”用“=”将告诉Oracle你所期望的“选择active_ids ID”返回只有一行。

或者:

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