python - Flask-SqlAlchemy 加载大量数据后插入速度极慢
问题描述
我有一张大约有 20 万条记录的表。我正在尝试使用 Flask-SqlAlchemy 批量插入大约 20 条记录。通常大约需要 20 毫秒,但是当我在插入之前从表中加载所有记录时,大约需要 1000 毫秒(慢 50 倍)。为什么?
from models import LocationMap, db
import random
import time
# the last line 'db.session.commit()' will be extremely slow when I uncomment this line.
#known_locations = LocationMap.query.all()
for i in range(10):
loc = LocationMap()
loc.longitude = 0 #location_batch[i + j][0]
loc.latitude = random.random() #location_batch[i + j][1]
loc.country = 'test'
loc.province = 'test2'
loc.city = 'test3'
loc.district = 'test4'
loc.township = 'test5'
db.session.add(loc)
st = time.time()
db.session.commit()
print(time.time() - st)
解决方案
我认为这与实例、引用、身份映射等的跟踪/状态有关。换句话说 - 我认为原因主要是相似ORM
的工作方式(sqlalchemy
不是很小ORM
)。这就是为什么这些类型的工具在处理大型数据集时性能较差的原因。但是它们具有非常强大的功能。
我将尝试用一个例子来解释:
locations = LocationMap.query.all()
locations[0].country = 'new value1'
locations[1].country = 'new value2'
for i in range(10):
# ... db.session.add(loc)
db.session.commit()
会发生什么?是的 - 我们将不仅有插入。我们还将有 2 个更新(new value1
, new value2
)。因为Session
具有对所有对象的引用。现在让我们尝试从 a 中删除选定的实例Session
:
locations = LocationMap.query.all()
db.session.expunge_all()
# your code here... for i in range(10):
您会看到该操作需要大约 20 毫秒(正常时间)。您还可以从 a 中删除特定对象Session
:
locations = LocationMap.query.all()
for l in locations:
# if we don't need reference anymore
db.session.expunge(l)
否则,ORM
如果性能对您至关重要,您可以拒绝。
推荐阅读
- ios - Obj-C - 将单元格从一个表格视图拖到另一个表格视图中?
- reactjs - 如何将 nextProps 传递给映射数组
- identityserver4 - Identityserver4 可以用于开放银行授权服务器实施吗?
- google-sheets - 计算 Google 表格列中前 80% 值的平均值
- python - 使用 python pandas 从 Dataframe 中删除记录
- amazon-web-services - 如何从快照中恢复 ebs
- laravel-5 - 如何解决 Laravel 页面上传到主机后无法正常加载的问题
- javascript - 单击 2 个按钮中的顶部按钮
- javascript - 如何按类名及其所有子标签提取标签
- vb.net - 启动程序时Form1_load代码不起作用