在Progress 4GL中,每个嵌套中使用'BREAK BY'的最有效方法是什么?

时间:2015-05-14 21:25:46

标签: progress-4gl openedge progress-db

假设有四个表,如GroupH,GroupL,Member,Incident。如果我为下面的每个编写嵌套,

for each GroupH use-index grouph-id
    NO-LOCK,
    each GroupL use-index groupl-id
    where GroupL.grphid = GroupH.grphid
    NO-LOCK,
    each Member use-index member-id
    where Member.memberid = GroupL.memberid
    NO-LOCK,
    each Incident use-index incident-key
    where Incident.memberid = Member.memberid
    NO-LOCK
    BREAK BY
        Member.memberid
        Member.schemid
        Member.emplid:

    //do something. 

end.

可能会导致我的查询与“BREAK BY”字段相比效率显着低下的事实是什么?

3 个答案:

答案 0 :(得分:1)

您可以做出的最大的积极变化是摆脱所有USE-INDEX短语,因为这会将数据库引擎限制为1指数并禁止索引包围。

除此之外,如果FOR EACH从最少量的数据到最大量的数据,那么这些都很好。

答案 1 :(得分:1)

使查询效率低下的重要因素是像USE-INDEX这样的错误编码会覆盖优化器以及WHERE子句标准与可用索引的不良对齐。

构建高效查询的最重要因素是WHERE子句指定涉及作为索引的主要组件的字段的相等匹配。

所有WHERE子句都使用相等匹配 - 这很好。

“GroupL.grphid = GroupL.grphid”是一个错字吗?你的意思是:

where GroupL.grphid = GroupH.grphid

在这种情况下,理想的情况是GroupL.grphid是某个索引中的第一个组件。如果该索引恰好是“groupl-id”,那么USE-INDEX没有任何损害。但是如果索引不是group-id,则阻止优化器使用它。 (允许编译器选择 - 在100名程序员中认为他们知道更好的999次是错误的几乎总是更好。)

同样适用于其他嵌套查询。我不知道实际的数据库模式和索引,我只能猜测,但似乎可能:

each Incident use-index incident-key
    where Incident.memberid = Member.memberid

有问题。我猜“事件密钥”可能不是“memberid”是第一个字段的索引。而你正在强迫它的使用。这可能不是一件好事。

在几乎所有其他规则都已用尽之后,BREAK-BY才会成为选择指数的决定性因素。它对查询性能没有显着影响。

如果没有可用于满足WHERE子句的索引,并且需要改进查询的性能,那么下一步操作就是添加一个符合需要的索引。

答案 2 :(得分:1)

除了汤姆所说的......帮自己一个忙,下载ProTop或者至少阅读_UserTableStat和_UserIndexStat虚拟系统表(VST)。

您可以使用它们来查看每个表正在读取的记录数。这使得很容易看出性能问题在哪里。