我有多个包含历史数据的表,因此 id 之间没有 1 对 1 的关系。
我必须加入 id 和指示数据何时处于活动状态的时间戳,如果数据仍然处于活动状态或从未为旧数据设置过,则 TO_TIMESTMP 可以为空。
一些分组后我的主表输出如下:
TABLE_A
AID USER_ID AMOUNT FROM_TIMESTMP TO_TIMESTMP
1 1 2 11/21/2012 00:00:00 12/04/2012 11:59:00
1 2 3 11/24/2012 12:00:00 null
2 1 2 11/21/2012 01:00:00 null
然后我有另一个表,我用它来进一步链接
TABLE_B
AID CID FROM_TIMESTMP TO_TIMESTMP HIST_ID
1 3 11/01/2012 00:00:00 null 1
1 3 11/21/2012 00:00:00 12/04/2012 11:59:00 2
1 3 11/24/2012 12:00:00 null 3
2 4 11/21/2012 00:59:59 null 4
我的第三张桌子看起来像这样:
TABLE_C
CID VALUE FROM_TIMESTMP TO_TIMESTMP HIST_ID
3 A 11/01/2012 00:00:00 null 1
3 B 11/21/2012 00:00:00 11/24/2012 11:59:00 2
3 C 11/24/2012 12:00:00 null 3
4 D 11/21/2012 01:00:01 null 4
如果我想将表 A 与表 C 到表 B 的值组合起来,我的预期输出是:
AID USER_ID AMOUNT FROM_TIMESTMP TO_TIMESTMP VALUE
1 1 2 11/21/2012 00:00:00 12/04/2012 11:59:00 B
1 2 3 11/24/2012 12:00:00 null C
2 1 2 11/21/2012 01:00:00 null D
除了表 A 中的 AMOUNT 和表 C 中的 VALUE 之外,所有内容都有索引,我使用以下 SQL 提取数据。
SELECT a.AID, a.USER_ID, a.AMOUNT, a.FROM_TIMESTMP, a.TO_TIMESTMP, c.VALUE from
(SELECT AID, USER_ID, SUM(AMOUNT), FROM_TIMESTMP, TO_TIMESTMP from TABLE_A GROUP BY AID, USER_ID, FROM_TIMESTMP, TO_TIMESTMP) a
inner join TABLE_B b on b.HIST_ID in (select max(HIST_ID) from TABLE_B
where AID = a.AID and FROM_TIMESTMP <= a.FROM_TIMESTMP+1/2880 and (TO_TIMESTMP>= a.FROM_TIMESTMP or TO_TIMESTMP is null))
inner join TABLE_C c on c.HIST_ID in (select max(HIST_ID) from TABLE_C
where CID = b.CID and FROM_TIMESTMP <= a.FROM_TIMESTMP+1/2880 and (TO_TIMESTMP>= a.FROM_TIMESTMP or TO_TIMESTMP is null));
由于保存数据的时间存在一些不一致,我在比较开始时间戳时添加了 30 秒的宽限期,以防它们大约在同一时间创建,有没有办法改进我这样做的方式?
我选择了具有 MAX(HIST_ID) 的那个,因此 TABLE_A 中的 AID=1 和 USER_ID=2 之类的情况只能从其他表中获取与 id/timestamp 匹配的最新行。
在我的真实数据中,我内部加入了 4 个这样的表(而不仅仅是 2 个),并且它在我的本地测试数据上运行良好(当询问所有数据时,在 11 秒内拉出超过 42000 行)。
但是,当我尝试在数据量更接近生产的测试环境中运行它时,即使我通过设置 FROM_TIMESTMP 必须在两个日期之间将我在第一个表中查询的行数限制为大约 6000 行,它的运行速度也会变慢。
有没有办法通过另一种方式来提高我加入表的性能?