pymysql的fetchall()之类方法会先在内存中缓存下所有查到的数据,然后再做处理。当结果集非常大时,将大量消耗内存资源。
解决方法:
使用SSCursor代替普通游标。这个cursor不会将数据复制到内存中,它从数据库存储块中读取记录,然后一条条返回。这样做的好处是客户端使用的内存少很多,并且当通过一个慢速网络或结果集非常大时,返回的行要快得多。
使用方法:在数据库连接时传入cursorclass参数,参数值为pymysql.cursors.SSCursor。
1 import pymysql 2 3 conn = pymysql.connect("IP", "user", "password", "database", cursorclass=pymysql.cursors.SSCursor) 4 cursor = conn.cursor() 5 6 query_sql = "select * from users" 7 8 cursor.execute(query_sql) 9 10 for row in cursor: 11 print(row) 12 13 cursor.close() 14 conn.close()
需要注意的是:
1. 因为SSCursor是没有缓存的游标,所以在结果集没有提取完之前,该游标的conn连接不能同时处理其他的SQL语句。即便使用此连接再创建一个cursor也不行。智能重新建立一个新的连接对象。
2. 超过60秒 MySQL会将连接断开,可以在建立连接时通过传入参数`init_command=("SET NET_WRITE_TIMEOUT=XX")`来增加超时时间。