假设有四个表,如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”字段相比效率显着低下的事实是什么?
答案 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)。
您可以使用它们来查看每个表正在读取的记录数。这使得很容易看出性能问题在哪里。