代码之家  ›  专栏  ›  技术社区  ›  Tmdean

查询到数据库中的搜索树

  •  3
  • Tmdean  · 技术社区  · 15 年前

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

    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个节点。在应用程序的生命周期中,记录的数量不会有太大的变化。最大深度为5。

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

    3 回复  |  直到 13 年前
        1
  •  1
  •   p.marino    15 年前

    我可能有点偏离了最初的问题,但现在我要说:

    正如评论中所建议的,考虑到您可以重写,您应该研究一种不同的方法来建模您的树结构,特别是考虑到您有一个“固定深度”,用不同的方法相当容易管理。

    在他的“SQL的艺术”中,Faroult倾向于一种基于在字符串字段中表示节点位置的方法,该字符串字段编码节点所在的“分支”。(有关这本书的回顾和一些讨论,请参阅 this Slashdot thread )

    这里是一个 online example 我的意思是,SQL的艺术在书中有一整节专门介绍这一点,比较了三种不同的方法(嵌套集、父/子关系表、编码路径字段),并以滑铁卢的军队的战斗顺序为例(有大量的查询,如“列出X将军下的所有营”或“找出谁是指挥官”)。炮兵Y组的ER”)。

    Faroult非常热衷于性能,整本书是一个非特定于供应商的集合,包含关于如何(重新)编写高效查询的非常合理和实用的建议。

        2
  •  0
  •   maxhugen    15 年前

    我可能只用一个 parent_id 表中的字段,并使用三向外部自联接获取目标 hierarchy 记录(适当筛选)加上它们的父记录(如果有)和子记录(如果有)。

        3
  •  0
  •   dnagirl    15 年前

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