1

我正在处理一个进行大量日期操作的查询(Oracle 11g)。使用行生成器,我正在检查另一个表中每个记录的日期范围内的每个日期。通过另一个查询,我知道我的行生成器需要生成 8500 个日期,并且这个数量每年会增长 365 天。另外,我正在检查的表有大约 18000 条记录,并且该表预计每年会增长数千条记录。

当将行生成器连接到另一个表以获取每条记录的日期范围时,问题就出现了。SQLTuning Advisor 说有一个昂贵的笛卡尔乘积,考虑到当前查询可以生成多达 8500 x 18000 条记录,这是有道理的。这是精简形式的查询,没有所有日期逻辑等:

with n as (
  select level n
  from dual 
  connect by level <= 8500
 )
select t.id, t.origdate + n origdate    
from (
    select id, origdate, closeddate
    from my_table
) t
join n on origdate + n - 1 <= closeddate -- here's the problem join
order by t.id, t.origdate;

在没有笛卡尔积的情况下,是否有另一种方法可以连接这两个表?

我需要计算每条记录的经过时间,不允许周末和联邦假期,以便我可以对经过的时间进行排序。此外,表格的分页是在服务器端完成的,所以我们不能只加载到表格中并在客户端进行排序。

目前系统中一条记录的最大年龄为3656天,平均为560天,还不如8500×18000差;但这仍然很糟糕。

我刚刚辞职来添加一个字段来存储开放日,计算一次并存储经过的时间,并创建一个计划任务以每晚更新所有开放记录。

4

1 回答 1

0

我认为如果稍微重写连接条件,您会获得更好的性能:

with n as (
  select level n
  from dual 
  connect by level <= 8500
 )
select t.id, t.origdate + n origdate    
from (
    select id, origdate, closeddate
    from my_table
) t
join n on Closeddate - Origdate + 1 <= n --you could even create a function-based index
order by t.id, t.origdate;
于 2014-02-18T20:09:05.500 回答