Join 在Firebird上只加入一次过程
我试图在Firebird查询中左连接两个存储过程。 在我的示例数据中,第一个返回70条记录,第二个仅返回1条记录Join 在Firebird上只加入一次过程,join,stored-procedures,firebird,Join,Stored Procedures,Firebird,我试图在Firebird查询中左连接两个存储过程。 在我的示例数据中,第一个返回70条记录,第二个仅返回1条记录 select --... from MYSP1('ABC', 123) s1 left join MYSP2('DEF', 456) s2 on s1.FIELDA = s2.FIELDA and s1.FIELDB = s2.FIELDB 问题在于性能:它需要10秒,而每个过程不到1秒。我怀疑程序会运行多次而不是一次。只执行一次是
select
--...
from MYSP1('ABC', 123) s1
left join MYSP2('DEF', 456) s2
on s1.FIELDA = s2.FIELDA
and s1.FIELDB = s2.FIELDB
问题在于性能:它需要10秒,而每个过程不到1秒。我怀疑程序会运行多次而不是一次。只执行一次是有意义的,因为我将固定参数传递给它们
有没有办法让Firebird只需执行每个过程一次,然后加入它们的结果?因为似乎没有办法,我在一个新的存储过程中运行这个查询,解决了这个问题,其中,我将来自
MYSP2
的所有结果缓存到全局临时表中,并在MYSP1
和临时表之间进行连接
这是临时表定义:
create global temporary table MY_TEMP_TABLE
(
FIELDA varchar(3) not null,
FIELDB smallint not null,
FIELDC varchar(10) not null
);
这是存储过程主体:
--cache MYSP2 results
delete from MY_TEMP_TABLE;
insert into MY_TEMP_TABLE
select *
from MYSP2('DEF', 456)
;
--join data
for
select
--...
from MYSP1('ABC', 123) s1
left join MY_TEMP_TABLE s2
on s1.FIELDA = s2.FIELDA
and s1.FIELDB = s2.FIELDB
into
--...
do
suspend;
但是,如果有另一个没有临时表的解决方案,那就太好了 也许这有助于:
with MYSP2W as (MYSP2('DEF', 456))
select
--...
from MYSP1('ABC', 123) s1
left join MYSP2W s2
on s1.FIELDA = s2.FIELDA
and s1.FIELDB = s2.FIELDB
当然不是,不过您可以尝试将这些存储过程中的两个子选择连接起来。“我没有时间去测试它是否真的有效。@Markrotterveel,谢谢,我试过你的建议,但它并没有提高性能。那么我恐怕没有办法;连接到存储过程的行为类似于横向连接(对驱动“表”中的每一行进行计算)。这些
FIELDA
和FIELDB
是任意生成的数据还是从某个字典表中获取的子集?@Arioch'它们只是从SPs返回的示例字段。名称是任意的。谢谢,但此查询无法运行。无论如何,我尝试使用WITH子句来封装其中一个过程,但没有任何变化。坦率地说,我将使用两个SP的结果(使用MERGE
)填充该表,然后从GTT中选择输出。这样,如果需要,您就可以不使用持久SP(第一部分作为executeblock
发送)。此外,请指定GTT是每个事务而不是每个连接。