3

我的数据库中有一个表代表一棵树。数据使用嵌套集存储。我想编写一个查询来搜索树并仅返回与模式匹配的节点,以及它们的祖先和后代。到目前为止,这是我想出的。

SELECT DISTINCT Node, Parent, Description
FROM Hierarchy 
INNER JOIN 
    (SELECT Lft, Rgt 
    FROM Hierarchy 
    WHERE Description LIKE '%SEARCHQUERY%') AS Matches 
ON (Hierarchy.Lft <= Matches.Lft AND 
    Hierarchy.Rgt >= Matches.Rgt) OR 
    (Hierarchy.Lft >= Matches.Lft AND 
    Hierarchy.Rgt <= Matches.Rgt) 
ORDER BY Description

这个查询有效,但是当子查询匹配很多描述时它有点慢。我正在寻找有关如何提高此查询性能的想法。

如果它是相关的,我正在使用 Access。

我很自由并且愿意改变表的结构来改进这个查询。该表有大约 8000 个节点。在应用程序的整个生命周期中,记录的数量不会发生太大变化。最大深度为五。

常规搜索的性能是可以接受的(返回约 200 个节点的搜索需要几秒钟),但在病理情况下需要几分钟(例如,如果搜索单个元音。但即使在这些情况下,子查询也需要更少比一秒钟执行)。

4

3 回答 3

1

我可能偏离了最初的问题,但我走了:

正如评论中所建议的那样,考虑到您可以负担得起重写,您应该研究一种不同的方式来为您的树结构建模,特别是考虑到您有一个“固定深度”,它可以通过不同的方法进行管理。

Faroult 在他的“The Art of SQL”中支持一种基于在字符串字段中表示节点位置的方法,该字符串字段编码节点所在的“分支”。(有关本书的评论和一些讨论,请参阅此 Slashdot 线程)。

这是我的意思的在线示例- SQL 的艺术有一整本书专门用于此,比较三种不同的方法(嵌套集,父/子关系表,编码路径字段)并使用战斗顺序以滑铁卢的军队为例(有很多查询,例如“列出 X 将军手下的所有营”或“找出谁是 Y 炮兵团的指挥官”)。

Faroult 对性能非常狂热,整本书都是关于如何(重新)编写有效查询的非常合理和实用的建议的非供应商特定集合。

于 2010-02-10T08:52:46.020 回答
0

我可能只使用parent_id表中的一个字段,并使用 3 路外部自连接来获取目标hierarchy记录(适当过滤)以及它们的父记录(如果有)和子记录(如果有)。

于 2010-02-09T05:28:10.853 回答
0

您的查询速度慢的原因是LIKE('%blah%')部分原因。如果你能放下第一%件事,速度会明显加快。或者,如果Access 支持 FULLTEXT 索引,则在 Description 字段中放置一个并执行MATCH(Description) AGAINST ('blah')

于 2010-02-09T15:52:13.507 回答