Стоит ли беспокоиться об исчерпании HierarchyID? - PullRequest
0 голосов
/ 15 мая 2010

Когда вы запрашиваете новый HierarchyID между двумя другими, результат становится все длиннее. Например, между 2 / 5.6 и 2 / 5.7 есть только 2 / 5.6.1 и другие 4 пути компонентов. Тип данных HierarchyID ограничен 800 байтами, поэтому вы не можете повторять это вечно. Опять же, целочисленные типы также ограничены, но на практике это не проблема. Должен ли я периодически дефрагментировать свой стол, чтобы высота не увеличивалась?

1 Ответ

1 голос
/ 15 мая 2010

Это считается «лучшей практикой» с hierarchyid для «добавления» новых идентификаторов, чтобы вы вообще не использовали эти промежуточные состояния (например, /2/5.6/). Если ваш hierarchyid является кластеризованным первичным ключом, то это плохо сказывается на производительности, это приведет к разбиению страницы, подобно тому, как uniqueidentifier.

Если вы создадите последовательных детей, маловероятно, что вам когда-нибудь придется беспокоиться о том, что они закончатся; Вы можете иметь буквально миллионы детей для каждого родителя.

Здесь - пример того, как вы должны генерировать 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

Если вы генерируете идентификаторы таким образом, будьте уверены, вам никогда не придется беспокоиться о том, что они закончатся.


Ради любопытства я провел быстрый тест, чтобы выяснить, насколько глубоко вы можете зайти. Вот тестовый скрипт:

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 является вашим кластеризованным индексом, это будет убивать производительность при разбиении страниц. Если вы пытаетесь ранжировать узлы по родителю, тогда вместо этого используйте столбец ранжирования ; и проще сортировать из более позднего SELECT, чем во время INSERT, когда вам приходится беспокоиться об изоляции транзакций и других подобных головных болях.

...