【发布时间】:2010-12-31 06:41:53
【问题描述】:
我现在正处于升级主要事务系统中的层次结构设计的最后阶段,并且我已经盯着这个 150 行查询(我将为您省去所有乏味的阅读)和认为必须有更好的方法。
问题的简要总结如下:
您将如何实现分层搜索,以匹配层次结构中不同级别的多个搜索词,并针对最快的搜索时间进行优化?
我找到了somewhat related question,但它实际上只占我实际需要的答案的 20% 左右。这是完整的场景/规范:
- 最终目标是在层次结构中的任意位置找到一个或多个任意项。
- 完整的层次结构大约有 80,000 个节点,预计在几年内增长到 1M。
- 整个层次结构路径的全文是唯一且具有描述性的;但是,单个节点的文本可能不是。这是一个商业现实,而不是一个轻率的决定。
- 示例:一个节点的名称可能类似于 “门”,它本身没有意义,但完整的上下文,“亚伦 > 房子 > 客厅 > 酒柜 > 门” ,意思很明确,它描述了特定位置的特定门。 (请注意,这只是一个示例,真正的设计远没有那么简单)
- 为了找到这个特定的门,用户可能会键入“aaron Liquid door”,这可能只会出现一个结果。查询被翻译为一个序列:一个包含文本“door”的项目,在一个包含文本“liquor”的项目下,另一个包含文本“aaron”的项目下。
- 或者,用户可能只需键入“house Liquid” 来列出人们家中的所有酒柜(这不是很好)。我明确提到这个例子是为了表明搜索不需要匹配任何特定的根或叶级别。该用户确切地知道他在寻找哪扇门,但不记得是谁拥有它,如果名字出现在他面前,他会记得。
- 所有术语都必须按照指定的顺序匹配,但正如上面的示例所示,层次结构中的级别可以“跳过”。术语“aaron booze cabinet”将不与此节点匹配。
- 平台是 SQL Server 2008,但我认为这是一个独立于平台的问题,并且不希望将答案限制在该平台上。
- 层次结构本身基于
hierarchyid(物化路径),索引为广度优先和深度优先。每个层次结构节点/记录都有一个要查询的Name列。基于节点的层次结构查询非常快,所以不用担心。 - 没有严格的层次结构 - 一个根可能根本不包含任何节点,也可能包含 30 个子树,这些子树散布到 10,000 个叶节点。
- 最大嵌套是任意的,但实际上它往往不超过 4-8 层。
- 层次结构可以而且确实会发生变化,尽管很少发生。任何节点都可以移动到任何其他节点,但有明显的例外(父节点不能移动到它自己的子节点等)
- 如果这不是已经暗示的:我确实可以控制设计,并且可以添加索引、字段、表,以及获得最佳结果所需的任何内容。
我的“梦想”是向用户提供即时反馈,就像在渐进式搜索/过滤器中一样,但我知道这可能是不可能的或极其困难的。我会对当前方法的任何重大改进感到满意,这通常需要 0.5 秒到 1 秒,具体取决于结果的数量。
为了完整起见,现有查询(存储过程)首先收集包含最终术语的所有叶节点,然后向上连接并排除路径与早期术语不匹配的任何叶节点。如果这对任何人来说都是落后的,请放心,这比从根开始并散开要有效得多。那是“旧”方式,每次搜索很容易花费几秒钟。
所以我的问题又来了:有没有更好(更有效)的方法来执行此搜索?
我不一定要寻找代码,只是寻找方法。我考虑了几种可能性,但它们似乎都有一些问题:
- 创建一个分隔的“路径文本”列并使用全文搜索对其进行索引。问题是在此列上的搜索也会返回所有子节点; “aaron house” 也匹配 “aaron house kitchen” 和 “aaron house basement”。
- 创建了一个
NamePath列,它实际上是一个嵌套的字符串序列,使用CLR 类型,类似于hierarchyid本身。问题是,我不知道微软如何能够将这种类型的查询“翻译”为索引操作,我什至不确定是否可以在 UDT 上进行。如果最终结果只是完整的索引扫描,那么我通过这种方法一无所获。
如果我不能做得比我已经拥有的更好,那并不是真正的世界末日;搜索“非常快”,没有人抱怨它。但我敢打赌,以前有人解决过这个问题并且有一些想法。请分享!
【问题讨论】:
-
+1 正确。当前的实现是做什么的?
-
另外,关卡的最大数量是多少?关卡的数量是固定的吗?
-
我确实试图解释当前的方法是什么。如果您可以更具体地说明不清楚的地方,我很乐意详细说明。
-
您将系统描述为“事务性”。这是否意味着层次结构本身会发生变化——删除或修改以及添加节点?此外,它只是叶节点还是可以添加整个路径?叶节点可以从一个分支移动到另一个分支吗?
-
@APC:好问题,答案是肯定的。我在问题中添加了关于此的注释。
标签: database performance database-design search hierarchy