pymysql--插入300万数据

需求: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-8
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远程连接用户名
        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秒!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏玩转全栈

Flutter中利用MapCache加sqflite实现一个伪LRU三级缓存

在做flutter应用的时候,遇到了一个问题,纯粹属于自己给自己加戏,问题是什么呢?我的app首页是一个列表,目前每次进应用,都是通过网络拿到新的列表,所以,如...

5244
来自专栏技术专栏

慕课网Flask构建可扩展的RESTful API-7. 权限控制

1.204 的HTTP状态码代表的是NO CONTENT,无内容。所以如果状态码是204,那么无论返回什么,前端都接受不到,但是我们要尽量返回格式化的信息,让前...

3004
来自专栏微信公众号:Java团长

彻底解决MySQL中文乱码

mysql是我们项目中非常常用的数据型数据库。但是因为我们需要在数据库保存中文字符,所以经常遇到数据库乱码情况。下面就来介绍一下如何彻底解决数据库中文乱码情况。

1892
来自专栏Golang语言社区

Golang拦截器的一种实现

前言 说起拦截器,大家一定会想起Java语言。 Java里的拦截器是动态拦截Action调用的对象,它提供了一种机制使开发者可以定义在一个action执行的前后...

54111
来自专栏青玉伏案

Swift3.0服务端开发(五) 记事本的开发(iOS端+服务端)

前边以及陆陆续续的介绍了使用Swift3.0开发的服务端应用程序的Perfect框架。本篇博客就做一个阶段性的总结,做一个完整的实例,其实这个实例在《Swift...

2267
来自专栏铭毅天下

Elasticsearch 6.X 新类型Join深入详解

0、ES6.X 一对多、多对多的数据该如何存储和实现呢? 引出问题: “某头条新闻APP”新闻内容和新闻评论是1对多的关系? 在ES6.X该如何存储、如何进行高...

2.6K9
来自专栏蓝天

一个简单的支持MySQL和SQLite3的DB接口

simple_db.zip 相关联代码:https://github.com/eyjian/mooon/tree/master/common_library/...

1022
来自专栏性能与架构

Mysql 8.0 新增特性

1. 数据字典 新增了事务型的数据字典,用来存储数据库对象信息 之前,字典数据是存储在元数据文件和非事务型表中的 2. 账号权限管理 添加了对 “角色” 的支持...

36411
来自专栏大学生计算机视觉学习DeepLearning

新手 php连接数据库大概。简单过程浅析以及遇到的问题分析

4336
来自专栏有趣的Python

5- Flask构建弹幕微电影网站-项目分析、搭建目录及模型设计项目优化与模型设计

已上线演示地址: http://movie.mtianyan.cn 项目源码地址:https://github.com/mtianyan/movie_proj...

4695

扫码关注云+社区