我正在开发一个执行大量日期操作的查询(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 x 18000差;但它仍然很糟糕。
我只是想让自己添加一个字段来存储开头,计算一次并存储已用时间,并创建一个计划任务来每晚更新所有打开的记录。
答案 0 :(得分: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;