1. 程式人生 > >利用python 實現快速插入300萬行數據

利用python 實現快速插入300萬行數據

async join rim spa san solid any mysql {}

需求:mysql怎麽快速插入300萬行數據?(效率要高)

分析:(1)使用pymysql多行插入(提高效率)

(2)使用python協程(遇到I/O操作就切換任務,無需等待--提高效率)

寫代碼之前的準備工作:

創建db20數據庫,創建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-8import pymysqlimport geventimport timeclass MyPyMysql:    def __init__(self, host, port, username, password, db, charset='utf8'):        self.host = host          # mysql主機地址        self.port = port          # mysql端口        self.username = username  # mysql遠程連接用戶名        self.password = password  # mysql遠程連接密碼        self.db = db              # mysql使用的數據庫名        self.charset = charset    # mysql使用的字符編碼,默認為utf8        self.pymysql_connect()    # __init__初始化之後,執行的函數    def pymysql_connect(self):        # pymysql連接mysql數據庫        # 需要的參數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後執行的函數        self.asynchronous()

    def run(self, nmin, nmax):        # 創建遊標        self.cur = self.conn.cursor()
        
        # 定義sql語句,插入數據id,name,gender,email        sql = "insert into userinfo(id,name,gender,email) values (%s,%s,%s,%s)"        # 定義總插入行數為一個空列表        data_list = []
        for i in range(nmin, nmax):
            # 添加所有任務到總的任務列表            result = (i, 'zhangsan' + str(i), 'male', 'zhangsan' + str(i) + '@qq.com')
            data_list.append(result)
            
        # 執行多行插入,executemany(sql語句,數據(需一個元組類型))        content = self.cur.executemany(sql, data_list)
        if content:
             print('成功插入第{}條數據'.format(nmax-1))
            
        # 提交數據,必須提交,不然數據不會保存        self.conn.commit()


    def asynchronous(self):        # g_l 任務列表        # 定義了異步的函數: 這裏用到了一個gevent.spawn方法        max_line = 10000  # 定義每次最大插入行數(max_line=10000,即一次插入10000行)        g_l = [gevent.spawn(self.run, i, i+max_line) for i in range(1, 3000001, max_line)]

        # gevent.joinall 等待所以操作都執行完畢        gevent.joinall(g_l)
        self.cur.close()  # 關閉遊標        self.conn.close()  # 關閉pymysql連接if __name__ == '__main__':
    start_time = time.time()  # 計算程序開始時間    st = MyPyMysql('192.168.11.102', 3306, 'py123', 'py123', 'db20')  # 實例化類,傳入必要參數    print('程序耗時{:.2f}'.format(time.time() - start_time))  # 計算程序總耗時

pycharm運行結果

技術分享圖片

以防萬一,在mysql裏面看看:

mysql> select count(1) from userinfo;
+----------+
| count(1) |
+----------+
|  3000000 |
+----------+1 row in set (0.78 sec)


300萬條數據不多不少,耗時87秒!

歡迎大家一起玩好PY,一起交流:QQ群:198447500

利用python 實現快速插入300萬行數據