【问题标题】:Why is sqlite delete table thousands of times slower from python than the sqlite3 shell?为什么 python 中的 sqlite delete table 比 sqlite3 shell 慢数千倍?
【发布时间】:2021-07-09 21:03:48
【问题描述】:

我有一个 SQLite 数据库(版本 3.31.1)。它有一个表 X,它有大约 3500 万行(每行有 3 列)。它也有一个索引。我正在尝试以两种不同的方式删除此表(在 Windows 10 上):

  1. 使用 sqlite shell "sqlite> DELETE FROM X;" --> 这需要 一两分钟
  2. 使用我的 python 应用程序和 sqlite3 库 (Python 3.9.1) --> 在我让它运行 5 小时 后它没有完成:
# "self" here is a class that holds the database connection
self.conn = sqlite3.connect("dbfile.db")
self.run_sql_command("PRAGMA foreign_keys = ON;")
self.run_sql_command("PRAGMA journal_mode = WAL;")
cursor = self.conn.cursor()
result = cursor.execute("DELETE FROM X;")   # This is where it stalls for hours
self.conn.commit()

你可以在上面的代码中看到我正在使用 WAL 模式(“PRAGMA journal_mode = WAL;”),虽然当我改成这个时,它只是加快了 shell 版本,似乎没有做任何事情蟒蛇版本。我也知道,python 方法在较小规模的语句(DELETE 以及其他语句,如 INSERT 和 SELECT 连接等)上运行得足够快。

在使用 python 方法时,有什么东西会导致完全相同的大规模 DELETE 语句产生如此巨大的差异吗?

【问题讨论】:

  • 你是不是先在shell里开启外键?您的表是否具有被其他表用作外键的键,反之亦然?
  • 不,我在 shell 中没有外键。是的,我肯定有跨表用作外键的键(因为几乎所有表都共享一个 ID)。听起来你认为这可能是负责任的?
  • 是的,这可能就是原因。处理 ON DELETE 子句和检查行是否可以删除的工作要少得多。

标签: python sql sqlite


【解决方案1】:

Shawn 对这个问题的评论就是答案,所以我只是把它放在这里作为公认的答案。我通过将删除代码包装在一个禁用外键(“PRAGMA foreign_keys = OFF;”)的语句中进行测试,然后在删除后重新启用它,Python 实现同样快。谢谢肖恩!

【讨论】:

    猜你喜欢
    • 2012-07-30
    • 2015-08-03
    • 2021-04-12
    • 2014-12-23
    • 2015-02-20
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    • 2014-10-04
    相关资源
    最近更新 更多