Join 在Firebird上只加入一次过程

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秒。我怀疑程序会运行多次而不是一次。只执行一次是

我试图在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秒。我怀疑程序会运行多次而不是一次。只执行一次是有意义的,因为我将固定参数传递给它们


有没有办法让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是每个事务而不是每个连接。