Sql oracle函数的延迟太大

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

这是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_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中的
相关的行


关于你的评论,你需要一个递归连接:不知道,我没有你的表或数据,但是-从你发布的到目前为止,看起来你有点错了

这就是您的查询所做的(考虑切换到explicit
JOIN
):

我的查询就是这样做的:

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);