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")`來增加超時時間。