我应该担心用完HierarchyID吗?

时间:2010-05-15 14:36:38

标签: sql-server hierarchy hierarchyid

当您在两个其他人之间请求新的HierarchyID时,结果会逐渐变长。例如,在2 / 5.6和2 / 5.7之间,只有2 / 5.6.1和其他4个组件路径。 HierarchyID数据类型限制为800个字节,因此您不能永远重复此操作。然后,整数类型也是有限的,但在实践中它不是问题。我应该定期对我的桌子进行碎片整理,以便高度不会无限制地增长吗?

1 个答案:

答案 0 :(得分:1)

它被认为是hierarchyid“附加”新ID的“最佳做法”,因此您根本不使用中间状态(例如/2/5.6/)。如果您的hierarchyid是群集主键,那么这对性能不利,则会导致页面拆分类似于uniqueidentifier的方式。

如果您生成顺序孩子,那么您不太可能需要担心用完; 每个父母,你可以拥有数百万的孩子。

Here是您希望如何生成hierarchyid值的示例:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION 
    UPDATE Hierarchy
    SET @LastChild = LastChild = HId.GetDescendant(LastChild, NULL)
    WHERE HId = @ParentID

    INSERT Hierarchy (HId, ...)
    VALUES (@LastChild, ...)
COMMIT

如果您以这种方式生成ID,请放心,您永远不必担心用完。


出于好奇,我进行了快速测试,以确定你能走多远。这是一个测试脚本:

DECLARE
    @parent hierarchyid,
    @child hierarchyid,
    @high hierarchyid,
    @cnt int

SET @parent = '/1/'
SET @child = @parent.GetDescendant(NULL, NULL)
SET @cnt = 0

WHILE (@@ERROR = 0)
BEGIN
    SET @cnt = @cnt + 1
    PRINT CAST(@cnt AS varchar(10)) + ': ' + @child.ToString()
    SET @high = @parent.GetDescendant(@child, @high)
    SET @child = @parent.GetDescendant(@child, @high)
END

您可以在点嵌套级别1426看到它出错,因此这是您可以创建多少“中间”节点的最坏情况限制,最坏情况意味着每个单个插入介于两个最深层嵌套的节点之间。

正如我在评论中所提到的,很难达到这个限制,但这仍然不是一个好主意。实际的字节长度越长,越长越用“点”,这会降低性能。如果hierarchyid是您的聚集索引,则会通过页面拆分 kill 性能。如果您尝试按父级对节点进行排名,则使用排名列;从SELECT开始对INSERT进行排序比从{{1}}进行排序更容易更加高效。在这种情况下,您必须担心事务隔离和其他此类问题。