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倍,加起来就能够满足快速插入的需求了

posted @ 2020-02-12 10:47  爱斯特拉冈  阅读(487)  评论(0编辑  收藏  举报