Sql 连接到一行表花费的时间太长

Sql 连接到一行表花费的时间太长,sql,oracle,performance,query-optimization,distributed-database,Sql,Oracle,Performance,Query Optimization,Distributed Database,我试图从一个表中读取所有产品代码(mal_no列)和数量数据(adet columns)(这是一个“hso”表,由mal_no索引,下面所有的表都有mal_no索引),但即使它只有一行数据,它也会继续运行,永远不会结束 没有此联接的查询(通过在下面仅添加注释掉的部分)是即时的 你对此有什么建议吗 谢谢 select mt.mal_no,hso.adet siparis, mot.birim_no,round((mbs.eldeki_stok_miktar*0.8),0) duzelts,

我试图从一个表中读取所有产品代码(mal_no列)和数量数据(adet columns)(这是一个“hso”表,由mal_no索引,下面所有的表都有mal_no索引),但即使它只有一行数据,它也会继续运行,永远不会结束

没有此联接的查询(通过在下面仅添加注释掉的部分)是即时的

你对此有什么建议吗

谢谢

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 mal_birim_ambar_detay@live mbs
  ,mal_tanim@live mt
  ,mss_temin_yeri_oncelik@live 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

从这么多的信息很难判断

但我建议您遵循以下步骤:

  • 如果您有数据库管理员或适当的工具,请检查执行计划。(例如,TOAD显示Oracle数据库的执行计划。)
  • 如果在嵌套循环中的执行计划中看到“完全扫描”,则表示数据库正在反复扫描表
  • 对于整体方法,您可以使用以下方法:

  • 在where条件项中,找到首先减少集合的条件项
  • (Oracle)使用索引提示和\u 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 mal_birim_ambar_detay@live mbs
         join mal_tanim@live mt
           on mbs.mal_no=mt.mal_no
         join mss_temin_yeri_oncelik@live 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所建议的,您可能会发现使用可以显著提高性能。因此,使用上面的内联视图,代码将启动

    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文档提供了进一步的指导

    连接看起来很好,你能给我们提供这些表的DDL/结构吗?我不太喜欢提示,但似乎在这里使用DRIVING_站点提示也会有所帮助。@BriteSponge-DRIVING_站点提示通常被认为是更安全的提示之一。这是一个很好的建议,我已将其纳入我的回答中,