避免不必要的表扫描

时间:2012-11-27 09:10:02

标签: sql oracle

Col 1,
col 2,
.....
.....
from 
table1,
table2
........
........
where
join conditions1
join conditions1
................
.................
and
table1.day_key >= (select key from date_dim where value='01-JAN-2011')
and table1.day_key <= (select key from date_dim where value='31-DEC-2011')
and 
table2.day_key >= (select key from date_dim where value='01-JAN-2011')
and table2.day_key <= (select key from date_dim where value='31-DEC-2011')

这里我可以看到date_dim表正在扫描四处的条件,如何避免它。在main from子句中未选择date_dim表。我没有环境来不幸地测试这个。数据库是oracle 10g

3 个答案:

答案 0 :(得分:1)

显而易见的答案是在date_dim(value)上添加索引。在执行此操作之前,请检查表中的行数。如果小于100,则表扫描根本不是坏事。

您可以避免将同一子查询包含两次,方法是将其移至cross join,例如:

from   ...
cross join
       (
       select  key 
       from    date_dim 
       where   value='01-JAN-2011'
       ) as dt1
....
where  table1.day_key >= dt1.key

答案 1 :(得分:1)

use can with子句从date_dim获取key的值,并在where子句中加入相同的值。 这将加速查询获取原因,同时使用with子句将值存储在临时空间中。

答案 2 :(得分:0)

正如我所说,我没有看到在必要时扫描该表两次的性能问题。

纯粹的重写查询将是:

select 
  Col 1,
  col 2,
from 
  table1,
  table2,
  date_dim date_dim_start,
  date_dim date_dim_end
where
  join conditions1
  join conditions1 and
  table1.day_key >=  date_dim_start.key and
  table1.day_key <= date_dim_end.key and
  table2.day_key >= date_dim_start.key and
  table2.day_key <= date_dim_end.key and
  date_dim_start.value = '01-JAN-2011' and
  date_dim_end.value='31-DEC-2011';

但你应该测试它,以免受到性能损失。