0

我有一个监视应用程序,它监视可能有子调用的调用。因此,如果我想读取监控数据,我想获取包括子调用在内的调用列表。调用可能会无限嵌套。

--开始编辑
在我当前的测试表中,大约有 700 万个条目。在生产使用中,它可能是两倍的大小。每个根条目的预期子代从 0 到大约 15 个,在极少数情况下可能有大约 50 个子代。层级很低,最高5级左右。

下面是我用我的数据模型读取有限数量的这些条目的方法。如果您对改进数据模型或查询有任何建议,我很乐意听取您的意见。
编辑结束——

基本上,我发现的所有论坛条目都是关于优化从一棵树而不是多棵树的阅读。

目前,我只有一张这样的表:

create TABLE montest2
(
   rootId VARCHAR(45) NOT NULL,
   messageId VARCHAR(45) NOT NULL,
   requestMessageId VARCHAR(45),
   sessionId VARCHAR(45),
   PRIMARY KEY (messageID)
);

rootId 对于属于一棵树的所有调用都是相同的。如果 sessionId 有一个值,我们就知道它是一个顶级(根)调用。messageId 对于每个调用都是唯一的。requestMessageId 将包含父母的 messageId。

现在我想阅读前 5 个 root 调用,包括他们的孩子。我可以使用这些语句来做到这一点:

编辑:请注意,我将问题缩小到此查询。我有一个额外的 WHERE 子句用于读取父母,以便我能够选择不同的父母。但是我的测试表明,这些并不是性能问题的原因。(编辑结束)。

  1. 读书家长:

    SELECT am.messageId montest2 am (am.sessionID IS NOT null ) 仅前 5 行

  2. 读书的孩子:

    SELECT ac.messageId FROM montest2 ac INNER JOIN ( SELECT am.rootID FROM montest2 am WHERE (am.sessionID 不为空) 仅获取前 5 行) 父在 ac.rootID = parents.rootID WHERE (ac.sessionID 为 NULL);

我知道第二个语句对于许多条目来说并不快。谁能给我一些建议如何优化这个查询?或者我应该对我的数据模型进行哪些更改?

PS:我使用 Derby 作为数据库,但它应该适用于任何数据库 - 它只是意味着更改限制(获取前 x 行)语法。

4

2 回答 2

1

我现在已经解决了我的问题如下:

我已将包含所有条目的单个表拆分为两个表。一个表包含树的所有根条目,另一个包含所有子项(以及子项的子项等)。
所以第一个查询是针对根表进行的,第二个查询是针对子表的。因为 children 表现在只有大约四分之一大小,所以查询速度要快得多。
此外,我意识到我的一个索引定义错误,因此它没有生效。当我使用 db2 工具在 db2 数据库上尝试我的问题时,我通过解释意识到了这一点。

所以,我给大家的提示:保持你的表小并使用解释来查看你的索引是否在做他们应该做的事情。

于 2012-05-31T07:57:58.120 回答
0

为什么不将连接移到 where 子句中,看看这是否更好?

SELECT messageId 
FROM montest2
WHERE rootID in (
         SELECT rootID from montest2 
         WHERE sessionID IS NOT null 
         FIRST 5 ROWS ONLY ) AND 
      sessionID IS NOT null
于 2012-05-21T11:53:44.797 回答