推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
Va1n3R
V2EX  ›  Python

CURDboy 问问各位,mysql 怎么多线程 insert 数据啊...

  •  
  •   Va1n3R · Dec 19, 2017 · 4590 views
    This topic created in 3248 days ago, the information mentioned may be changed or developed.

    python3 写了个爬虫。
    多线程爬取数据写入数据库
    一开始使用的是 sqllite3,一直提示 database is blocked,后来发现 sqllite 不支持多线程读写
    然后谷歌搜了一下,看到了别人推荐使用 mysql 来做这种任务...我只会基础的 CURD 操作,用了简单的多线程来操作,然而 mysql 貌似也不能直接多线程插入数据,stackoverflow 里面的老哥们说是需要建立连接池...头疼,之前只接触过基础的操作,请各位 V2er 赐教
    python3 代码:

    def getExin():
        while not Q.empty():
            i = Q.get()
            .*
            try:
                .*
            except :
                continue
            try:
                c.execute("INSERT INTO exin (username, password) \
                      VALUES (%s,'%s')" % (username, password))
                conn.commit()
            except:
                pass
    
    
    for i in range(0, 99475):
        if len(str(i)) < 5:
            i = (5 - len(str(i))) * "0" + str(i)
        Q.put(i)
    
    threads = []
    
    conn = connect(user='root', password='root', database='test')
    c = conn.cursor()
    for i in range(800):
        x = threading.Thread(target=getExin,args=())
        threads.append(x)
    for t in threads:
        t.start()
    c.close()
    print("All done")
    
    24 replies  •  2017-12-20 16:20:48 +08:00
    misaka19000
    misaka19000
    Dec 19, 2017
    1
    一个线程对应一个链接就行了
    Va1n3R
    Va1n3R
    OP
    Dec 19, 2017 via iPhone
    3
    @misaka19000 尝试过会提示连接不上,我这里是 1000 线程
    zeraba
    zeraba
    Dec 19, 2017 via Android
    4
    executemany 不行么 是什么场景非要多线程多个事务去写入哪
    Va1n3R
    Va1n3R
    OP
    Dec 19, 2017
    5
    @zeraba 访问一次目标获取一次信息,然后写入数据库,就这么简单的逻辑,但是单线程太慢了...
    zeraba
    zeraba
    Dec 19, 2017 via Android
    6
    @Va1n3R 要么一次一次写 redis 要么把取回的数据先存成 list 或者 tuple 到了一定的量再批量插入 mysql 你这么搞 太费资源了
    Va1n3R
    Va1n3R
    OP
    Dec 19, 2017
    7
    @zeraba 资源不是问题,只是不想把简单问题复杂化,谢谢老哥啦
    Cooky
    Cooky
    Dec 19, 2017 via Android
    8
    你这只是一个连接多线程使用吧
    kiwi95
    kiwi95
    Dec 19, 2017
    9
    你现在 Q 是共享的,那 Q 的 get,put 是不是阻塞的?然后多个线程也是操作一个连接作数据插入,这样多线程有什么意义呢,除非你的数据准备阶段占时间开销的大头,否则这样并不能提升速度
    likuku
    likuku
    Dec 19, 2017
    10
    老生常谈提示下:得用 InnoDB
    Va1n3R
    Va1n3R
    OP
    Dec 19, 2017
    11
    @Cooky 我尝试过多线程每个都链接一次,但是 mysql 会拒绝我的访问....我开了 800~1000 的线程
    Va1n3R
    Va1n3R
    OP
    Dec 19, 2017
    12
    @kiwi95 Q 是 queue,应该不会阻塞吧,速度提升确实肉眼可见啊...
    Sanko
    Sanko
    Dec 19, 2017 via Android
    13
    executemany 应该不慢吧
    Va1n3R
    Va1n3R
    OP
    Dec 19, 2017
    14
    @Sanko
    @zeraba 数据量挺大的,直接放入字典,我怕内存会爆啊
    Cooky
    Cooky
    Dec 19, 2017 via Android
    15
    @Va1n3R 看看 MySQL 默认最大连接数多少,改下配置
    HanSonJ
    HanSonJ
    Dec 20, 2017
    16
    这种情况,批量 insert 最佳

    插入速度优化上百倍
    billlee
    billlee
    Dec 20, 2017
    17
    你如果不批量插入,开再多线程,HDD 上一秒也只能提交 100 个事务。
    jimzhong
    jimzhong
    Dec 20, 2017
    18
    你开多线程获得的性能提升未必有批量插入大。
    huhujin
    huhujin
    Dec 20, 2017
    19
    我瞎比说说:
    for i in range(800):
    x = threading.Thread(target=getExin,args=())
    t.setDaemon(True)
    x.start()
    2ME
    2ME
    Dec 20, 2017
    20
    不懂 py .. 不过你这么搞肯定有问题 线程开太高 mysql 最大连接数会有问题 就算连得上 你 IO 还是会有问题 和#18 说的一样 你开多线程不一定有拼接 sql 批量插入来的实在
    catinred
    catinred
    Dec 20, 2017
    21
    中间用个队列把数据存起来 然后起个线程批量插入就好了
    exiaohao
    exiaohao
    Dec 20, 2017
    22
    这种事吧,celery 就好啦 gevent 开起来妈妈再也不用担心并发上不去了
    搞 thread 多麻烦
    Va1n3R
    Va1n3R
    OP
    Dec 20, 2017
    23
    @2ME 已经采用了 executemany 啦
    Va1n3R
    Va1n3R
    OP
    Dec 20, 2017
    24
    @exiaohao 之前没有写过协程、异步。昨晚看了一下,启发很大
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1124 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 48ms · UTC 23:22 · PVG 07:22 · LAX 15:22 · JFK 18:22
    ♥ Do have faith in what you're doing.