Sql oracle函数的延迟太大
这是bill表的一个示例:(billnr不是唯一的。renr、filnr、kassanr的组合是唯一的) 我需要renr、filnr、kassanr的唯一组合的总和(价格),如果他们有resnr 100。 也就是说:10+15+6=31 我有一个疑问:Sql oracle函数的延迟太大,sql,oracle,plsql,sql-function,Sql,Oracle,Plsql,Sql Function,这是bill表的一个示例:(billnr不是唯一的。renr、filnr、kassanr的组合是唯一的) 我需要renr、filnr、kassanr的唯一组合的总和(价格),如果他们有resnr 100。 也就是说:10+15+6=31 我有一个疑问: select sum(rk.price) from bill rk, (select rk1.renr, rk1.filnr, rk1.kassanr from bill rk1 where rk1.res_nr = :IN_n_r
select sum(rk.price)
from bill rk,
(select rk1.renr, rk1.filnr, rk1.kassanr from bill rk1 where rk1.res_nr = :IN_n_resnr) tr
where rk.filnr = tr.filnr
and rk.kassanr = tr.kassanr
and rk.renr = tr.renr;
当我执行这个查询时,只需要7秒,这是可以的!
但是当我在函数中写这个时,函数需要21秒,我不明白为什么
CREATE OR REPLACE FUNCTION FUN_TEST (IN_n_resnr in number) return number
is
v_return number := null;
begin
select sum(rk.price) into v_return
from bill rk,
(select rk1.renr, rk1.filnr, rk1.kassanr from bill rk1 where rk1.res_nr = :IN_n_resnr) tr
where rk.filnr = tr.filnr
and rk.kassanr = tr.kassanr
and rk.renr = tr.renr;
return(v_return);
end;
我试图用with子句编写函数。但这也需要21秒
with t_resnr as
(select rk1.renr, rk1.filnr, rk1.kassanr from bill rk1 where rk1.res_nr = IN_n_resnr)
select sum(rk.price) into v_return
from bill rk,
t_resnr tr
where rk.filnr = tr.filnr
and rk.kassanr = tr.kassanr
and rk.renr = tr.renr;
你的问题不简单吗
select sum(rk.price_euro)
from bill rk
where rk.res_nr = :in_n_resnr
内联视图做什么?无,但筛选与\n\u resnr中的相关的行
关于你的评论,你需要一个递归连接:不知道,我没有你的表或数据,但是-从你发布的到目前为止,看起来你有点错了
这就是您的查询所做的(考虑切换到explicitJOIN
):
我的查询就是这样做的:
SQL> select sum(a.sal)
2 from emp a
3 where a.deptno = 10;
SUM(A.SAL)
----------
13750
SQL>
结果是一样的
再一次:我没有您的表或数据,但是-除了我的版本应该表现更好之外,没有什么不同。我建议你试试看会发生什么
另外,如果您发布了测试用例,我们将能够看到您真正拥有什么,并且您可以解释您期望从中得到什么结果。以下是我编写查询的方式:
select sum(price)
from bill
where (renr, filnr, kassanr) in
(select renr, filnr, kassanr from bill where res_nr = :IN_n_resnr);
您想查看renr、filnr、kassanr的组合,因此应该有一个索引:
create index idx1 on bill (renr, filnr, kassanr);
对于这样的组合,我们希望看到价格,我们可以将其添加到指数中,以更快地得到它
create index idx1 on bill (renr, filnr, kassanr, price);
但我们只想看一下具有特定res\u nr
项的组合。DBMS可以采取两种可能的方法:
首先获取res\u nr
的所有组合,然后使用该列表查找与价格相关的行
循环遍历所有行,并针对每个行检查是否存在具有res\u nr
的相关行
对于方法1,我们希望
create index idx2 on bill (res_nr);
甚至更好
create index idx2 on bill (res_nr, renr, filnr, kassanr);
对于方法2,我们希望采用相反的顺序:
create index idx3 on bill (renr, filnr, kassanr, res_nr);
我将提供以下索引:
create index idx1 on bill (renr, filnr, kassanr);
create index idx2 on bill (res_nr, renr, filnr, kassanr);
create index idx3 on bill (renr, filnr, kassanr, res_nr);
然后在解释计划中查看DBMS使用的是哪一个,去掉其他的。No。这并不是那么简单。我们需要一个递归连接。一项法案有一些保留意见。但是一张账单也有更多没有保留的项目和一些愚蠢的栏目。正如我所说,这个问题是正确的。问题在于函数。我添加了更多信息。请看一看,这不适合我们的桌子。因为我们的DBA是dumm。filnr是“门店号”。Kassanr是“收银台”,renr是“票据编号”。问题是“卡桑”和“比尔纳”并不是唯一的。我们需要精确现金台精确存储的精确账单。但是,您正在将来自账单表的数据与来自同一账单表的数据合并。很抱歉,我恐怕我们彼此不了解。@Littlefoot不要让您误用Q中的公式,检查样本bill
数据:renr、filnr、kassanr的组合不是唯一的;这就不同了。显然OP想说的是,如果您限制resnr=100
,那么这些列是唯一的,因为我们的DBA是dumm。filnr是“门店号”。Kassanr是“收银台”,renr是“票据编号”。问题是“卡桑”和“比尔纳”并不是唯一的。我们需要准确的账单在准确的收银台旁边的准确的商店里。bilnr不是主键。有一个随机主键。账单桌上叫了别的什么。是的。组合是唯一的。请为两个查询发布执行计划,发布您希望从子查询和账单表返回多少行。有关如何发布的提示,请参阅。顺便说一句,您可以在内部解决DBA的问题,在这里您可以发布一个具有正确列命名的示例<代码>加入
<代码>加入
JOIN
。也许您只是缺少一个唯一的约束/索引唯一的列组合。顺便说一句,看起来DBA做得很正确(除了缺少约束/索引)。
create index idx3 on bill (renr, filnr, kassanr, res_nr);
create index idx1 on bill (renr, filnr, kassanr);
create index idx2 on bill (res_nr, renr, filnr, kassanr);
create index idx3 on bill (renr, filnr, kassanr, res_nr);