背景:目前表中只有5G(後期持續增加),可是其中一個字段(如下稱爲detail字段)存了2M(不必定2M,部分爲0,平均下來就是2M),字段中存的是一個數組,數組中存N個json數據。這個字段以下:python
[{"A": "A", "B": "B", "C": "C", "D": "D"}...]
要是拆表的話,可能要拆好多個,要是存多行根據阿里巴巴《Java 開發手冊》提出單錶行數超過 500 萬行,也不是很建議。但願有大佬能指教一下。
回到正題,一開始是分兩個表存儲,一個表存基本信息(A表),一個表(B表)存關聯字段,及detail字段。貌似沒有啥用,按需求現要將兩張表合在一塊兒供BI去處理。直接複製了那張基礎字段的A表,經過遍歷B表根據關聯字段進行更新。可是在select的時候內存讀入的數據太大直接卡死(狗頭)。因而在網上查找如何經過pymysql處理大數據的問題。解決方案以下:mysql
import pymysql up_db = pymysql.connections.Connection(host=MYSQL_HOST, port=MYSQL_PORT, user=MYSQL_USER, password=MYSQL_PASSWORD, db=MYSQL_DB, charset='utf8mb4',) count = 0 while True: # if count == 2: # break select_sql = "select sec_report_id,detail from sec_report_original_data_detail limit %s,2"%(count) up_cursor = up_db.cursor() up_cursor.execute(select_sql) result = up_cursor.fetchall() for data in result: sec_report_id = data[0] detail = data[1] update_sql = "update `sec_report_original_data_intact` set detail = '%s' where `sec_report_id` = '%s' " % ( db.escape_string(detail), sec_report_id) print(update_sql) res = up_cursor.execute(update_sql) if res: print(res) up_db.commit() print(f'{sec_report_id}插入成功') count+=2
能夠解決問題,不過只是拿了幾條作測試(我用的是第二種),這裏沒寫終止條件,有朋友要用的話本身加上。sql
SSCursor
沒有緩存的遊標
pymysql.cursors.SSCursor
代替默認的cursor
會從數據庫中一條一條的讀取記錄,從而不會形成內存卡死,可是也有須要注意的地方:數據庫
import pymysql db = pymysql.connections.Connection(host=MYSQL_HOST, port=MYSQL_PORT, user=MYSQL_USER, password=MYSQL_PASSWORD, db=MYSQL_DB, charset='utf8mb4', cursorclass=pymysql.cursors.SSDictCursor) up_db = pymysql.connections.Connection(host=MYSQL_HOST, port=MYSQL_PORT, user=MYSQL_USER, password=MYSQL_PASSWORD, db=MYSQL_DB, charset='utf8mb4',) up_cursor = up_db.cursor() cursor = pymysql.cursors.SSCursor(db) select_sql = "select sec_report_id,detail from sec_report_original_data_detail" cursor.execute(select_sql) result = cursor.fetchone() try: while result is not None: sec_report_id = result[0] detail = result[1] update_sql = "update `sec_report_original_data_intact` set detail = '%s' where `sec_report_id` = '%s'"%(db.escape_string(detail),sec_report_id) res = up_cursor.execute(update_sql) if res: print(res) up_db.commit() print(f'{sec_report_id}插入成功') result = cursor.fetchone() except Exception as e: print(e) finally: up_cursor.close() cursor.close() db.close()
解決了一次性讀取大數據的方法,可是沒找到特別好的存儲那個
detail
字段中數據的辦法,有朋友瞭解的能夠溝通一下。json