【问题标题】:Django MPTT - how expensive is objects.rebuild?Django MPTT - objects.rebuild 有多贵?
【发布时间】:2013-05-13 06:29:35
【问题描述】:

我将在接下来的几天推出一个使用 Django MPTT 来管理分层数据的应用程序。 MPTT 提供了一个名为rebuild 的函数,它重建了给定模型可用的所有树,因此称为TreeNodes.objects.rebuild()。如您所见,该命令是在模型上调用的,而不是在模型实例上调用的。必须在将节点插入树后调用此命令。

对于 Django MPTT 0.6(尚未正式使用 released),实现了 partial_rebuild 命令,它只会重建给定的树。

虽然在本地测试最多 10 棵树,但根本没有性能问题,但我担心我的数据库中有 100 棵树,我正在调用 rebuild 命令(这将重建所有 100 棵树树),这可能是一个重要的性能问题。

有使用rebuild 命令经验的人吗?

【问题讨论】:

  • 你有什么理由定期重建你的树?
  • 据我了解 Django-mptt 在向树添加节点后总是必须重建树,如下所示: node.parent = parent , node.save() ,它必须遵循TreeNodes.objects.rebuild() 命令。
  • 您是否在没有任何后续重建的情况下测试了您的操作结果?我敢说,这根本没有必要。看看 TreeManager 的实现。
  • 是的,你可能是对的。我想我遇到了 mptt 如何设置节点的左右值的问题。如果我总是在子节点的末尾添加节点,它们很好,但如果我在子节点的开头添加节点,则设置错误。对于最后一种情况,我的 order_insertion_by 元设置似乎被忽略了。有趣的是,重建修复了左右值。无论如何,我将进行更多测试,并让您知道结果是什么。

标签: django performance django-mptt


【解决方案1】:

供以后参考..

objects.rebuild() 仅在某些特殊情况下需要。通常 mptt 仅通过设置节点的父 id 来正确设置节点的左右值。 docs中也提到了这一点

我遇到了未正确设置左右值的问题,因为我保存了新节点!之前!我重置了其他已经存在的兄弟姐妹的位置值。当为具有元属性order_insertion_by 设置的树插入新节点时,必须首先重置所有兄弟节点的 order_insertion_by 值,然后保存新节点。这样 mptt 就能够正确地重新计算左右值。

请参阅下面的(简化)示例:

models.py

class Node(MPTTModel):
    """
    Representation of a single node
    """
    name = models.CharField(max_length=200)
    parent = TreeForeignKey('self', null=True, blank=True, related_name='%(app_label)s_%(class)s_children')
    position = models.PositiveIntegerField(max_length=10) #for nodes on the same hierarchy level we have to define the position in which they are displayed 

    class MPTTMeta:
        order_insertion_by = ['position']

views.py

new_node = Node(name="new node", parent=parent_node, position=1)
update_node_positions(new_node, 1) #routine to update the node positions
new_node.save()

update_node_positions

def update_node_positions(node, mode):
    """
    Procedure to update the node positions
    Three different modes available:
        1 = insert node
        2 = update position, parent stays the same
        3 = update position and change parent
        4 = trashed
    """

    if mode == 1 or mode==3:
        #if node has been inserted at the beginning
        if node.position == 1:
            node.get_siblings().update(position=F('position') + 1)
        #if node has been inserted not at beginning and not at the last position
        elif node.position != node.get_siblings().count() + 1:
            #update positions of siblings right of node by one
            node.get_siblings().filter(position__gte=node.position).update(position=F('position') + 1)
        if mode == 3:
            #since we removed the node from a parent, we have to decrement the positions of the former siblings right of the node by one
            if node._original_parent is not None:
                #do updates only for nodes which had a parent before. will not be executed for root nodes
                node._original_parent.get_children().filter(position__gt=node._original_position).update(position=F('position') - 1)
    if mode == 2:
        #if old position is left of new position -> decrement position by 1 for nodes which have position <= node.position AND > node.original_position
        if node.position > node._original_position:
            node.get_siblings().filter(Q(position__lte=node.position) & Q(position__gt=node._original_position)).update(position=F('position') - 1)
        #if old position is right of new position -> increment position by 1 for nodes which have position >= node.position AND < node.original_position 
        if node.position < node._original_position:
            node.get_siblings().filter(Q(position__gte=node.position) & Q(position__lt=node._original_position)).update(position=F('position') + 1)
    if mode == 4:
        #decrement position by 1 for nodes which have position > node.position
        node.get_siblings().filter(Q(position__gt=node.position)).update(position=F('position') - 1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 2016-06-07
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    相关资源
    最近更新 更多