zoukankan      html  css  js  c++  java
  • sqlalchemy_mptt一次调优

     

    问题背景:

      我用sqlalchemy_mptt构建了一个多级分类项目,数据库用了sqlite。随着数据条数越来越多,写入速度逐渐变慢,一棵树的插入甚至需要1分钟,远远不能满足需求

    分析思路:

      1. 批量插入

      代码中使用的是

    session.add(node)
    session.commit()

      我首先怀疑因数据逐条插入,导致速度慢。试图换成批量插入。

    session.bulk_insert_mappings(Tree, insert_rows)

      但批量插入需要手动实现一个预排序树,这样一来再用sqlalchemy_mptt就没有意义了,只会徒增系统复杂性,遂放弃。

      2. 建索引

      通过读sqlalchemy_mptt 的源码,我发现在数据插入(包括删改)的时候,有两个关键查找操作:

      

    # 建一颗新的树时,需要寻找当前库中最大的tree_id
    func.max(table.c.tree_id) + 1
    
    # 子节点插入时,每次都要查询父节点的rgt, lft, level等字段
    table_pk == instance.parent_id

      而sqlalchemy_mptt 在混入ORM对象时,只对rgt, lft, level 设置了索引,导致每次 CRUD操作都需要从头到尾查找。

    解决方案:

      添加两个索引:

    treeid_idx = Index('treeid_idx', Tree.tree_id)
    treeid_idx.create(bind=engine)
    parent_idx = Index('parent_idx', Tree.parent_id)
    parent_idx.create(bind=engine)

      经测试,添加tree_id索引大约能快4倍,添加parent_id大约快100倍,加起来就能够满足快速插入的需求了

  • 相关阅读:
    GET请求和POST请求的本质区别
    go切片的Add与Del
    滚动到指定位置的问题
    promise---批量调用接口,等待所有的请求发完
    this argument
    html2canvas截图 下载图片
    数组合并去重
    vue项目踩坑
    关于java中的栈和堆
    用python实现一个最简单版本的mysql数据库连接池
  • 原文地址:https://www.cnblogs.com/estragon/p/12298128.html
Copyright © 2011-2022 走看看