成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么PyMySQL獲取一條數據會讓內存爆炸

開發 前端
當Python 有讀寫 MySQL 數據的需求時,我們經常使用PyMySQL這個第三方庫來完成。

 當Python 有讀寫 MySQL 數據的需求時,我們經常使用PyMySQL這個第三方庫來完成。

[[317112]]

有時候如果一張表里面的數據非常大,但是我們只需要讀取一條數據,此時我們可能會想當然地使用cursor.fetchone()這個方法,以為這樣就真的可以只讀取一條數據:

 

  1. import pymysql 
  2.  
  3.  
  4. connection = pymysql.connect(host='localhost'
  5.                              user='user'
  6.                              password='passwd'
  7.                              db='db'
  8.                              charset='utf8mb4'
  9.                              cursorclass=pymysql.cursors.DictCursor) 
  10.                               
  11. with connection.cursor() as cursor
  12.     db = 'select * from users where age > 10' 
  13.     cursor.execute(db) 
  14.     one_user = cursor.fetchone() 

但實際上,上面這段代碼,與下面這段代碼沒有任何區別:

 

  1. ... 
  2. with connection.cursor() as cursor
  3.     sql = 'select * from users where age > 10' 
  4.     cursor.execute(sql) 
  5.     all_users = cursor.fetchall() 
  6.     one_user = all_users[0] 

這是因為,當我們執行到cursor.execute(sql)的時候,PyMySQL就已經把表里面所有的數據讀取到內存中了。而后面的cursor.fetchall()或者cursor.fetchone()只不過是從內存中返回全部數據還是返回1條數據而已。

我們來看PyMySQL的源代碼[1]。在cursor.execute()方法代碼如下圖所示:

 

 

其中第163行調用了self._query方法。我們再去到這個方法里面:

 

看到代碼第322行,調用了self._do_get_result()方法。我們再去這個方法里面看看:

 

注意代碼第342行,此時已經把所有數據存放到了self._rows列表中。

現在我們來看cursor.fetchone()方法:

 

可以看到,這里不過是從列表里面根據下標讀取一條數據出來而已。

再看cursor.fetchall()方法:

 

如果之前先多次調用過cursor.fetchone(),那么self.rownumber會持續增加。而調用cursor.fetchall()時,跳過之前已經返回過的數據,直接返回剩下的全部數據即可。如果之前沒有調用過cursor.fetchone(),那么直接返回全部數據。

所以,單純使用cursor.fetchone()并不能節省內存,如果表里面的數據非常大,還是會有內存爆炸的危險。

那么真正的解決辦法是什么呢?真正的解決辦法在創建數據庫連接的時候指定游標類型。pymysql.connect有一個參數叫做cursorclass,把它的值設定為pymysql.SSDictCursor即可解決問題。

我們來看一下如何正確使用它:

 

  1. import pymysql 
  2.  
  3.  
  4. connection = pymysql.connect(host='localhost'
  5.                              user='user'
  6.                              password='passwd'
  7.                              db='db'
  8.                              charset='utf8mb4'
  9.                              cursorclass=pymysql.cursors.SSDictCursor) 
  10.                               
  11. with connection.cursor() as cursor
  12.     db = 'select * from users where age > 10' 
  13.     cursor.execute(db) 
  14.     for row in cursor
  15.         print('對 cursor 直接進行迭代,每循環一次,從數據庫讀取一條數據。不會提前把所有數據讀取到內存中。'
  16.         print(row['name']) 

 

責任編輯:華軒 來源: 未聞Code
相關推薦

2023-06-18 23:13:27

MySQL服務器客戶端

2019-06-24 11:07:34

數據數據庫存儲

2020-09-03 20:10:23

Elasticsear存儲數據

2025-04-02 04:33:00

CPU服務器時鐘頻率

2019-03-28 10:09:49

內存CPU硬盤

2018-03-30 09:42:05

2024-09-09 08:15:20

2023-09-01 14:07:00

ChatGPTGPT數據分析

2024-04-19 07:31:58

MySQL數據庫

2025-04-01 05:22:00

JavaThread變量

2021-02-09 09:50:21

SQLOracle應用

2024-02-01 18:07:37

2022-10-18 08:38:16

內存泄漏線程

2020-03-27 16:05:49

數據庫數據MySQL

2021-12-02 15:30:55

命令內存Linux

2018-04-24 14:58:06

內存降價漲價

2022-05-18 08:25:59

MySQLutf8字符集數據庫

2012-06-20 16:22:57

2012-11-08 14:28:16

2013-06-19 10:55:40

Disruptor并發框架
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品视频在线观看 | 精品成人在线视频 | 日韩欧美在线视频 | 日韩三级电影在线看 | 一区二区视频免费观看 | 亚洲一区二区三区在线免费观看 | 欧美成人猛片aaaaaaa | 日本五月婷婷 | 日韩视频a | 黄瓜av| 日韩视频在线一区 | 麻豆精品国产91久久久久久 | 在线一区视频 | 特级毛片 | 亚洲欧美一区二区三区国产精品 | 波多野结衣中文字幕一区二区三区 | 91久久国产综合久久91精品网站 | 亚洲在线视频 | 中文在线播放 | av午夜电影 | 亚洲 欧美 综合 | 午夜99| 亚洲精品精品 | 精品欧美一区二区三区久久久 | 久久人人国产 | www.婷婷 | 精品蜜桃一区二区三区 | 在线成人福利 | 国产一区免费 | 国产精品日韩一区二区 | 国产成人精品综合 | 午夜电影福利 | 人人干97| 丁香色婷婷 | 亚洲精品在线免费播放 | 99国内精品久久久久久久 | 亚洲成人精品在线观看 | 国产精品久久久久久久久久久久久 | 中文字幕1区2区3区 亚洲国产成人精品女人久久久 | 久久精品视频网站 | 成人午夜在线观看 |