0%

sqlalchemy查询大量数据导致内存使用过高

背景

使用sqlalchemy查询数据时,一般会这样查询:

1
session.query(Model).all()

但是当查询的数据量比较大时,可能会因为内存占用过大而被操作系统kill。

其他方式

遍历

1
2
3
query = session.query(Model)
for obj in query:
pass

yield_per()

1
2
3
objs = session.query(Model).yield_per()
for obj in objs:
pass

测试内存占用

下面测试三种使用方式分别占用的内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from memory_profiler import profile
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from app.models.models import TimingData

engine = create_engine(
'mysql+pymysql://root:hzmcdba@192.168.239.27/dg-ins?charset=utf8'
)
Session = sessionmaker(engine)


@profile
def test():
with Session() as session:
datas = session.query(TimingData).limit(1000).yield_per(100)
for data in datas:
pass


if __name__ == "__main__":
test()

测试结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
11
​```

​```
222
​```

​```
333
​```

## 总结

综上所述,查询大量数据时应该使用yield_per()函数,可以大量节约内存。