两个进度查询之间的有效差异

时间:2015-04-24 08:56:36

标签: openedge progress-db

任何人都可以解释一下为什么当我运行一个正在进行的查询时,它只在一个表上运行它只在几秒钟内运行,当我运行一个查询作用于多个表时,它会在几个小时内运行。我使用的是否有任何错误的东西?

我的最后一次尝试是:

FOR EACH multipos.mp_loja NO-LOCK,
    EACH multipos.mp_acmp NO-LOCK,
    EACH multipos.mp_mvlj NO-LOCK

    WHERE mp_mvlj.lj_cod    = mp_loja.lj_cod 
      AND mp_mvlj.mvl_dtmov =  mp_acmp.mvl_dtmov:

           /* EXPORT ... */

END.

到现在为止,我改为:

    FOR EACH multipos.mp_mvlj NO-LOCK WHERE mp_mvlj.mvl_dtmov = 04/20/2015,
    EACH multipos.mp_loja NO-LOCK WHERE mp_loja.lj_cod = mp_mvlj.lj_cod,
    EACH multipos.mp_acmp NO-LOCK WHERE mp_acmp.lj_cod = mp_mvlj.lj_cod 
                                    AND mp_acmp.mvl_dtmov = mp_mvlj.mvl_dtmov:

    /* EXPORT */

END.

现在,这是最有效的方式吗?

1 个答案:

答案 0 :(得分:1)

您没有指定将mp_loja加入mp_acmp的条件。

所有关于可用的索引和调用它们的WHERE子句都是关于它的。为了获得良好的性能,您必须使用作为索引的主要组件的字段。任何不足都会导致表格扫描。

使用XREF编译代码。您将在输出中看到WHOLE-INDEX。这意味着您正在执行表扫描。如果你在连接的每次迭代中扫描整个表,那将是非常非常痛苦的。如果你做到这两个层次,那将是完全荒谬的。

WHERE子句中的字段必须是所选表中索引的前导组件(或唯一组件)。否则Progress不能对查询进行括号,并且必须进行表扫描以评估条件。

理想情况下,mp_mvlj表上有一个唯一索引,lj_cod和mvl_dtmov是唯一的字段。

您还需要一个将mp_loja连接到mp_acmp的唯一索引。

仔细查看WHERE子句和可用的索引。如果没有合适的索引,您可能需要添加一个索引。

您当前的代码相当于3个嵌套的FOR EACH循环:

for each mp_loja no-lock:  /* no WHERE, scan the entire table */

  for each mp_acmp no-lock:  /* no WHERE, scan the entire table ON EVERY ITERATION of the outer loop which is scanning it's entire table!!! */

    for each mp_mvlj no-lock
      where mp_mvlj.lj_cod    = mp_loja.lj_cod 
        and mp_mvlj.mvl_dtmov =  mp_acmp.mvl_dtmov:  /* WHERE of unknown quality, but we are executing it on every iteration of the two outer loops */

      /* export ... */

    end.

  end.

end.

我不相信我尝试使用“sports2000”数据库进行实验。在我的副本中有3,948个订单记录和13,970个订单行记录。

define variable i as integer no-undo.

for each order no-lock,
    each orderline no-lock:

  i = i + 1.

end.

display i.

我得到i = 55,153,560。恰好是3,948 * 13,970。 非常需要很长时间才能执行。

与之对比:

define variable i as integer no-undo.
for each order no-lock,
    each orderline no-lock where orderline.ordernum = order.ordernum:

  i = i + 1.

end.

display i.

更快,更快。 i = 13,942(我的sports2000副本中有28个孤立的订单行......)