加入到1行表需要太多时间

问题描述:

我想从表中读取所有产品代码(mal_no列)和数量数据(adet列)(这是“hso”表和mal_no索引,下表中的所有表具有mal_no的索引),但即使它只有一行数据,它仍然运行并永不结束。加入到1行表需要太多时间

没有此连接的查询(通过仅添加注释掉的部分)即时。

你有什么建议吗?

感谢,

select mt.mal_no,hso.adet siparis, 
    mot.birim_no,round((mbs.eldeki_stok_miktar*0.8),0) duzelts, 
    mot.oncelik, 
    SUM(round((mbs.eldeki_stok_miktar*0.8),0)) OVER(ORDER BY 
    mot.oncelik desc ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) kumule_stok 
from [email protected] mbs 
    ,[email protected] mt 
    ,[email protected] mot 
    ,web_hso hso 
where 1=1 
and hso.mal_no=mbs.mal_no 
and mbs.mal_no=mt.mal_no 
and mbs.birim_no=mot.birim_no 
and mt.mal_grup_no=mot.mal_grup_no 
and mt.mal_altgrup_no=mot.mal_altgrup_no 
--and mt.mal_no in ('1035541001') 
and mbs.eldeki_stok_miktar>0 
and mot.oncelik>0 
and mbs.ambar_no='01' 
order by mot.oncelik desc 
+0

连接似乎okkay,你可以或许提供给我们这些表的DDL /结构。 –

这是很难从这么多的信息告诉。

但我建议你遵循这个步骤:

  1. 如果您有任何数据库管理员或者,如果你有合适的工具,检查执行计划。 (例如,TOAD显示Oracle数据库的执行计划。)
  2. 如果在嵌套循环内的执行计划中看到“全面扫描”,则表示数据库一遍又一遍地扫描表。 where条件的项目找到它首先降低设定的那些

    1. 其中:

    对于整体的方法,你可以使用这些方法。

  3. (Oracle)使用索引提示和use_nl提示来显式定义数据库,它应该如何去表。

最后,对于一个原则,尽量避免大连接。划分并征服你的数据。尝试编写嵌套循环并在检索数据时尽可能多地使用索引。

您正在将三个表从远程数据库连接到本地数据库中的一个表。像这样的分布式查询速度很慢,因为数据必须通过两个数据库之间的网络发送。

本地数据库将发送子查询到远程数据库;但加入和过滤发生在本地,所以可能会从远程数据库传输大量冗余数据。因此,您需要为优化器提供足够的信息,以便可以创建巧妙的子查询。

例如,在隔离线视图远程表:

select rmt.mal_no, 
     hso.adet siparis, 
     rmt.birim_no, 
     rmt.duzelts, 
     rmt.oncelik, 
     rmt.kumule_stok 
from web_hso hso 
    join 
     (select mt.mal_no, 
       mot.birim_no, 
       round((mbs.eldeki_stok_miktar*0.8),0) duzelts, 
       mot.oncelik, 
       SUM(round((mbs.eldeki_stok_miktar*0.8),0)) 
       OVER(ORDER BY mot.oncelik desc ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) kumule_stok 
from [email protected] mbs 
    join [email protected] mt 
     on mbs.mal_no=mt.mal_no 
    join [email protected] mot 
     on mbs.birim_no=mot.birim_no 
     and mt.mal_grup_no=mot.mal_grup_no 
     and mt.mal_altgrup_no=mot.mal_altgrup_no 
     where mbs.eldeki_stok_miktar>0 
     and mot.oncelik>0 
     and mbs.ambar_no='01') rmt 
    on hso.mal_no=rmt.mal_no 
    order by rmt.oncelik desc 

显然,这只是一种猜测,因为我不明白你的数据模型和数据。你需要在这里应用你的领域知识来制作一个好的查询。单独的内联视图可能无法提供您所需的全部速度。例如,如果大多数工作涉及到三个远程表上的连接,并且很可能是这样,那么@BriteSponge建议您可能发现使用the driving_site hint可以显着提高性能。因此,使用上面的内联视图,代码将开始

select /*+DRIVING_SITE(rmt)*/ 
     rmt.mal_no, 
     hso.adet siparis, 
     rmt.birim_no, 
     rmt.duzelts, 
     rmt.oncelik, 
     rmt.kumule_stok 
from web_hso hso 
    join (...) rmt 
    on hso.mal_no=rmt.mal_no 

Oracle文档有进一步的指导。 Find out more

+0

我不太喜欢提示,但它看起来像使用DRIVING_SITE提示也可能在这里帮助。 – BriteSponge

+0

@BriteSponge - DRIVING_SITE提示通常被认为是更安全的提示之一。这是一个很好的建议,我已经将其纳入我的答案, – APC