如何加速 SQLAlchemy 中的混合属性查询?

def*_*cal 2 python sql postgresql sqlalchemy

有没有一种好方法可以加快查询 SQLALchemy 中涉及关系的混合属性?我有以下两个表:

class Child(Base):
     __tablename__ = 'Child'
     id = Column(Integer, primary_key=True) 
     is_boy = Column(Boolean, default=False)
     parent_id = Column(Integer, ForeignKey('Parent.id'))


class Parent(Base):
     __tablename__ = 'Parent'
     id = Column(Integer, primary_key=True) 
     children = relationship("Child", backref="parent")

     @hybrid_property
     def children_count(self):
         return self.children_count.count()

     @children_count.expression
     def children_count(cls):
         return (select([func.count(Children.id)]).
            where(Children.parent_id == cls.id).
            label("children_count")
            )
Run Code Online (Sandbox Code Playgroud)

当我跨 50,000 行查询 Parent.children_count 时(每个父级平均大约有 2 个子级),它非常慢。是否有通过索引或其他方式来加速这些查询的好方法?

Jef*_*man 5

默认情况下,PostgreSQL 不会在外键上创建索引。

所以我要做的第一件事就是添加一个索引,SQLAlchemy 让它变得非常简单:

parent_id = Column(Integer, ForeignKey('Parent.id'), index=True)
Run Code Online (Sandbox Code Playgroud)

考虑到当前数据集的大小,这可能会导致足够快的检索时间——试试看。请务必连续尝试几次查询以预热 PostgreSQL 缓存。

对于更大的数据集,或者如果查询仍然不够快,您可以考虑预先计算计数并缓存它们......缓存的多种方法,最简单的黑客可能是在您的父项中抛出一个额外的列表并确保每当添加新子项时,您编写应用程序逻辑来增加计数。这样有点hacky。另一种选择是在 Redis/memcache 中缓存计数,甚至使用物化视图(如果计数偶尔会过时几分钟,这是一个很好的解决方案)。