我需要调整下面提到的这个查询,以避免每次都与存档表合并,因为即使在大多数情况下,数据将出现在第一个表本身中,下面的查询也可能不必要地扫描了存档表。 / p>
const yourMessage: TokenMessage = {
token: '',
// ...
};
function iReturnMessage(): TokenMessage {
return {
token: ''
// ...
};
}
答案 0 :(得分:1)
您可以对主表添加not exists
检查作为归档分支的一部分:
select o.status_code,o.order_id
from order o
where o.order_id=p_order_id
union all
select a.status_code,a.order_id
from order_archive a
where a.order_id=p_order_id
and not exists (
select *
from order o
where o.order_id=p_order_id
);
这现在当然意味着它将查看两个分支中的主表;但它可能仍然更快,具体取决于您的数据,索引,统计信息等。
另一个选项可以防止查看存档表(如果ID存在于主表中),首先对主表进行简单计数,然后有条件地打开ref游标以针对两个可能的查询之一每个表一张;即在PL / SQL中而不是在SQL中进行分支,从而完全消除了联合。像这样:
procedure status(p_order_id in varchar2, p_stat out sys_refcursor) is
l_count pls_integer;
begin
select count(*) into l_count
from order o
where o.order_id=p_order_id;
if l_count > 0 then
-- exists in main table so only query that
open p_stat for
select o.status_code,o.order_id
from order o
where o.order_id=p_order_id;
else
-- does not exist in main table so only query archive
open p_stat for
select a.status_code,a.order_id
from order_archive a
where a.order_id=p_order_id;
end if;
end status;
/
如果ID在主表中不是唯一的,则可以将and rownum = 1
添加到初始查询中,以便在找到任何匹配的行后立即停止(因此l_count
最多为1)而不是获得准确的计数,因为您实际上并不在乎所找到的实际数字。
我们可以在订单表的数据集上使用提取和循环吗?如果找到,则仅用于存档表
并非如此,因为获取将占用结果的第一行。这是一个非常人为的例子:
var rc refcursor;
declare
x varchar2(1);
begin
open :rc for
select 'A' from dual where 1 = 0
union all
select 'B' from dual where 1 = 0;
fetch :rc into x;
if :rc%notfound then
open :rc for select 'C' from dual;
end if;
end;
/
PL/SQL procedure successfully completed.
print rc
'
-
C
通过这种设置,“ main”查询找不到任何行(由于1 = 0
检查);提取游标后,游标是notfound
,因此它将重新打开游标以进行“存档”查询,并且调用方会按预期看到该游标。
但是如果第一个查询确实返回行:
declare
x varchar2(1);
begin
open :rc for
select 'A' from dual where 1=1
union all
select 'B' from dual where 1=1;
fetch :rc into x;
if :rc%notfound then
open :rc for select 'C' from dual;
end if;
end;
/
PL/SQL procedure successfully completed.
print rc
'
-
B
然后在获取游标之后是found
,因此它不会为存档查询重新打开游标,并且现有的ref游标将传递回调用方。但是游标的第一行已经被提取到x
变量中并且丢失了,因此调用者不再能看到该行。 print
仅显示带有'B'
的一行,而缺少应该包含'A'
的另一行。
要使呼叫者仍然看到两行,则必须使用“ main”查询重新打开光标:
declare
x varchar2(1);
begin
open :rc for
select 'A' from dual where 1=1
union all
select 'B' from dual where 1=1;
fetch :rc into x;
if :rc%found then
open :rc for
select 'A' from dual where 1=1
union all
select 'B' from dual where 1=1;
else
open :rc for select 'C' from dual;
end if;
end;
/
PL/SQL procedure successfully completed.
print rc
'
-
A
B
从逻辑上讲,我想这实际上与我在上面进行的初始计数相同,但是不清楚。
答案 1 :(得分:0)
第一步很容易使用from my_module import x, y, z, zz, zzz
,因为UNION ALL
保证了两个表的UNION
结果。
使用distinct
将从第一个表中获取数据,并且只有从其中获取了所有行之后,才可以访问第二个表。
UNION ALL
和UNION
相同并且您需要对其进行分解时,才需要 order_id
。这不是典型的情况。