十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊
量身定制 + 運營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
需求:MySQL怎么快速插入300萬行數(shù)據(jù)?(效率要高)
成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于做網(wǎng)站、網(wǎng)站建設(shè)、青羊網(wǎng)絡(luò)推廣、微信小程序、青羊網(wǎng)絡(luò)營銷、青羊企業(yè)策劃、青羊品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供青羊建站搭建服務(wù),24小時服務(wù)熱線:13518219792,官方網(wǎng)址:www.cdcxhl.com
分析:(1)使用pymysql多行插入(提高效率)
(2)使用python協(xié)程(遇到I/O操作就切換任務(wù),無需等待--提高效率)
寫代碼之前的準(zhǔn)備工作:
創(chuàng)建db20數(shù)據(jù)庫,創(chuàng)建userinfo表
mysql> create database db20; Query OK, 1 row affected (0.00 sec) mysql> use db20; Database changed mysql> create table userinfo(id int primary key auto_increment,name varchar(20),gender varchar(6),email varchar(40)); Query OK, 0 rows affected (0.05 sec) mysql> desc userinfo; +--------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(20) | YES | | NULL | | | gender | varchar(6) | YES | | NULL | | | email | varchar(40) | YES | | NULL | | +--------+-------------+------+-----+---------+----------------+4 rows in set (0.03 sec)
pymysql代碼
#!/usr/bin/env python # coding: utf-8 ##技術(shù)交流 QQ群:198447500 ###說明:該代碼僅限python學(xué)習(xí)研究使用,請謹(jǐn)慎復(fù)制粘貼直接使用,一定要懂哈。 import pymysql import gevent import time class MyPyMysql: def __init__(self, host, port, username, password, db, charset='utf8'): self.host = host # mysql主機地址 self.port = port # mysql端口 self.username = username # mysql遠(yuǎn)程連接用戶名 self.password = password # mysql遠(yuǎn)程連接密碼 self.db = db # mysql使用的數(shù)據(jù)庫名 self.charset = charset # mysql使用的字符編碼,默認(rèn)為utf8 self.pymysql_connect() # __init__初始化之后,執(zhí)行的函數(shù) def pymysql_connect(self): # pymysql連接mysql數(shù)據(jù)庫 # 需要的參數(shù)host,port,user,password,db,charset self.conn = pymysql.connect(host=self.host, port=self.port, user=self.username, password=self.password, db=self.db, charset=self.charset ) # 連接mysql后執(zhí)行的函數(shù) self.asynchronous() def run(self, nmin, nmax): # 創(chuàng)建游標(biāo) self.cur = self.conn.cursor() # 定義sql語句,插入數(shù)據(jù)id,name,gender,email sql = "insert into userinfo(id,name,gender,email) values (%s,%s,%s,%s)" # 定義總插入行數(shù)為一個空列表 data_list = [] for i in range(nmin, nmax): # 添加所有任務(wù)到總的任務(wù)列表 result = (i, 'zhangsan' + str(i), 'male', 'zhangsan' + str(i) + '@qq.com') data_list.append(result) # 執(zhí)行多行插入,executemany(sql語句,數(shù)據(jù)(需一個元組類型)) content = self.cur.executemany(sql, data_list) if content: print('成功插入第{}條數(shù)據(jù)'.format(nmax-1)) # 提交數(shù)據(jù),必須提交,不然數(shù)據(jù)不會保存 self.conn.commit() def asynchronous(self): # g_l 任務(wù)列表 # 定義了異步的函數(shù): 這里用到了一個gevent.spawn方法 max_line = 10000 # 定義每次最大插入行數(shù)(max_line=10000,即一次插入10000行) g_l = [gevent.spawn(self.run, i, i+max_line) for i in range(1, 3000001, max_line)] # gevent.joinall 等待所以操作都執(zhí)行完畢 gevent.joinall(g_l) self.cur.close() # 關(guān)閉游標(biāo) self.conn.close() # 關(guān)閉pymysql連接 if __name__ == '__main__': start_time = time.time() # 計算程序開始時間 st = MyPyMysql('192.168.11.102', 3306, 'py123', 'py123', 'db20') # 實例化類,傳入必要參數(shù) print('程序耗時{:.2f}'.format(time.time() - start_time)) # 計算程序總耗時
pycharm運行結(jié)果
以防萬一,在mysql里面看看:
mysql> select count(1) from userinfo; +----------+ | count(1) | +----------+ | 3000000 | +----------+1 row in set (0.78 sec)
300萬條數(shù)據(jù)不多不少,耗時87秒!
歡迎大家一起玩好PY,一起交流:QQ群:198447500