【发布时间】:2021-08-17 02:57:13
【问题描述】:
免责声明:我是数据库新手,这是我在 StackOverflow 上的第一个问题。很高兴编辑以使其尽可能清晰和符合代码。
在我的应用程序中,我有两个表:InputData(我的应用程序下载的外部数据)和 OutputData(我的应用程序创建的数据)。一个或多个 InputData 可用于创建一个或多个 OutputData,当一个 InputData 项目被删除时,我想删除所有使用已删除项目作为输入创建的 OutputData。本质上是与级联删除的多对多关联。
对我来说很幸运,至少我是这么想的,the SQLAlchemy docs 中有一个我想做的确切示例。然而,在实现它并使用它之后,我发现它非常慢。
我做了一些基准测试,发现 100,000 个 InputData,每个都有一个 OutputData 子项(总共 100,000 个 OutputData)需要将近 10 分钟才能删除。相比之下,具有级联删除功能的一对多模型只需 30 秒即可删除数量级大的表。
经过大量研究,我真的只有两个想法:
- 我对多对多级联的成本非常幼稚,实际上删除 2 个表中的 200,000 行需要 10 分钟是有道理的。
- 删除 InputData 项时,将遍历整个 OutputData 表以检查哪些 OutputData 行引用了已删除项作为其父项。这在我的直觉中当然是有道理的,特别是因为我读过有关 Postgres 不会自动在外键上创建索引的文章,但我找不到任何人遇到相同问题或如何解决它的示例。
- 我删除的方式不对。上述基准只是
db.session.query(InputData).delete()
db.session.commit()
我的表格(正是来自不同名称的文档):
association_table = Table('association', Base.metadata,
Column('input_data_id', Integer, ForeignKey('input_data.id', ondelete="CASCADE")),
Column('output_data_id', Integer, ForeignKey('output_data.id', ondelete="CASCADE"))
)
class InputData(Base):
__tablename__ = 'input_data'
id = Column(Integer, primary_key=True)
children = relationship(
"OutputData",
secondary=association_table,
back_populates="inputs",
cascade="all, delete",
)
class OutputData(Base):
__tablename__ = 'output_data'
id = Column(Integer, primary_key=True)
parents = relationship(
"InputData",
secondary=association_table,
back_populates="outputs",
passive_deletes=True
)
提前谢谢你!
【问题讨论】:
标签: python postgresql sqlalchemy flask-sqlalchemy