Python 在sqlite中更新NULL对于大型数据库来说速度太慢
我有一个约529M行的sqlite数据库表。我之所以选择sqlite,是因为对db的写操作不会太多,而主要是读操作,我希望在单个文件中使用它的简单性。不幸的是,我在生成数据库时犯了一个错误:现在我必须通过与另一个表的内部联接来更改两列中的一些空值 表格格式:Python 在sqlite中更新NULL对于大型数据库来说速度太慢,python,sqlite,Python,Sqlite,我有一个约529M行的sqlite数据库表。我之所以选择sqlite,是因为对db的写操作不会太多,而主要是读操作,我希望在单个文件中使用它的简单性。不幸的是,我在生成数据库时犯了一个错误:现在我必须通过与另一个表的内部联接来更改两列中的一些空值 表格格式: >>> cdr ego_id alter_id date tower_id city state 123 456 20200101 98766
>>> cdr
ego_id alter_id date tower_id city state
123 456 20200101 98766 Los Angeles California
789 143 20200105 09232 NULL NULL
789 143 20200105 42106 NULL NULL
>>> towermap
tower_id city state
98766 Los Angeles California
09232 Rochester New York
我想要的是在cdr中检查空值,并用towermap中对应于tower_id的城市、州值替换它们。结果应该是:
>>> cdr
ego_id alter_id date tower_id city state
123 456 20200101 98766 Los Angeles California
789 143 20200105 09232 Rochester New York
789 143 20200105 42106 NULL NULL
这是我使用sqlalchemy执行的原始SQL,我使用的是Python。sqlite似乎无法使用内部联接进行更新,因此我在阅读了答案后编写了以下代码
我预计约有3500万行具有空值,这些空值可能会被替换,也可能不会被替换,这取决于towermap中是否存在它们的tower_id。已经18个小时了,数据库日志仍然在变大。记忆似乎不是问题
我的代码可以进一步优化速度吗?我可以加上类似的东西
PRAGMA synchronize=OFF;但如果可能的话,我会避免这样做 您可以使用表示法使用单个子查询更新两列,从而将每个匹配行上必须完成的工作量减少一半:
UPDATE cdr
SET (city, state) = (SELECT city, state FROM towermap WHERE tower_id = cdr.tower_id)
WHERE (city IS NULL OR state IS NULL)
towermap.tower_id应该有一个索引,如果它不象主键那样。完整的表定义总是比列名称列表更好。是否存在只有一列city和state为null的情况?@forpas这是可能的。我发现了一个语法错误,这很奇怪,因为我检查了上面的链接,这是推荐的。似乎错误在SET city的某个地方,state part.UPDATE cdr SET city,state=SELECT city,state FROM towermap,其中tower\u id=cdr.tower\u id,其中city为NULL或state为NULL回溯最近一次调用:File UPDATE\u NULL\u loc\u db.py,第125行,main*sys.argv File UPDATE\u NULL\u loc\u db.py,第117行,在main c.executeupdate_query sqlite3.OperationalError:near:syntax中error@irene检查您的SQLite版本。行值从3.15.0版开始受支持,谢谢。我已经更新了SQLite版本,现在正在构建索引。一旦我用行值运行完代码,我会通知你的!最后用索引运行它,大约需要20分钟。谢谢!
UPDATE cdr
SET (city, state) = (SELECT city, state FROM towermap WHERE tower_id = cdr.tower_id)
WHERE (city IS NULL OR state IS NULL)