python使用多线程查询数据库的实现示例


Posted in Python onAugust 17, 2020

一.背景:

         当数据量过大时,一个程序的执行时间就会主要花费在等待单次查询返回结果,在这个过程中cpu无疑是处于等待io的空闲状态的,这样既浪费了cpu资源,又花费了大量时间(当然这里主要说多线程,批量查询不在考虑范围,总会存在不能批量查询的情况),在这种非密集型运算(及大量占用cpu资源)的情况下在python中无疑运用多线程是一个非常棒的选择。

二.知识点:

        数据库连接池的运用及优势,python中多线程的运用,队列的运用

        数据库连接池:限制了数据库的连接最大个数,每次连接都是可以重复使用的,当然也可以限制每个连接的重复使用次数(这个在这里是没必要的),需要注意的是设置的数据库的最大连接个数最好要大于我们自己开的最大线程个数,一般逻辑是每个线程占用一个数据库连接可以使程序达到最大速度,如果小于则可能存在同时连接个数大于数据库允许的最大连接个数的风险。使用数据库连接池的优势在于,python多线程并发操作数据库,会存在链接数据库超时、数据库连接丢失、数据库操作超时等问题,而数据库连接池提供线程间可共享的数据库连接,并自动管理连接。

       python多线程:在程序等待io的时间里调用多线程去数据库执行查询操作。

       队列:这个就是数据结构里面的知识了,一般队列的常用模式先进先出队列。(这里主要用的是队列取一个数就少一个数的原理,其实用列表也可以实现,他的先进先出主要强调的是一个顺序关系,这一点到没用上,就当是练练手了)

三.两段代码作比较:

数据库的截图:

python使用多线程查询数据库的实现示例

第一段代码:正常循环查询并打印出执行时间

#!/usr/bin/python
# -*- coding=utf-8 -*-
import time
import threading
import MySQLdb
import Queue
from MySQLdb.cursors import DictCursor
from DBUtils.PooledDB import PooledDB

def mysql_connection():
  host = 'localhost'
  user = 'root'
  port = 3306
  password = '123456'
  db = 'test'
  charset = 'utf8'
  limit_count = 3 # 最低预启动数据库连接数量
  pool = PooledDB(MySQLdb, limit_count, maxconnections=15, host=host, user=user, port=port, passwd=password, db=db, charset=charset,
      use_unicode=True, cursorclass=DictCursor)
  return pool


start = time.time()
pool = mysql_connection()

for id in range(50):
  con = pool.connection()
  cur = con.cursor()
  sql = '''select id,name,age,weight from test where id = %s '''%id
  cur.execute(sql)
  time.sleep(0.5)
  result = cur.fetchall()
  if result:
    print('this is tread %s (%s,%s,%s,%s)'%(id,result[0]['id'],result[0]['name'],result[0]['age'],result[0]['weight']))
  else:
    print('this tread %s result is none'%id)

end = time.time() - start
print(end)

执行结果:

python使用多线程查询数据库的实现示例

第二段代码:限制数据库连接池最大15个连接,用队列限制最大线程个数为10个

#!/usr/bin/python
# -*- coding=utf-8 -*-
import time
import threading
import MySQLdb
import Queue
from MySQLdb.cursors import DictCursor
from DBUtils.PooledDB import PooledDB

def mysql_connection():
  host = 'localhost'
  user = 'root'
  port = 3306
  password = '123456'
  db = 'test'
  charset = 'utf8'
  limit_count = 3 # 最低预启动数据库连接数量
  pool = PooledDB(MySQLdb, limit_count, maxconnections=15, host=host, user=user, port=port, passwd=password, db=db, charset=charset,
      use_unicode=True, cursorclass=DictCursor)
  return pool

def tread_connection_db(id):
  con = pool.connection()
  cur = con.cursor()
  sql = '''select id,name,age,weight from test where id = %s '''%id
  cur.execute(sql)
  time.sleep(0.5)
  result = cur.fetchall()
  if result:
    print('this is tread %s (%s,%s,%s,%s)'%(id,result[0]['id'],result[0]['name'],result[0]['age'],result[0]['weight']))
  else:
    print('this tread %s result is none'%id)
  con.close()


if __name__=='__main__':
  start = time.time()
  #创建线程连接池,最大限制15个连接
  pool = mysql_connection()
  #创建队列,队列的最大个数及限制线程个数
  q=Queue.Queue(maxsize=10)
  #测试数据,多线程查询数据库
  for id in range(50):
    #创建线程并放入队列中
    t = threading.Thread(target=tread_connection_db, args=(id,))
    q.put(t)
    #队列队满
    if q.qsize()==10:
      #用于记录线程,便于终止线程
      join_thread = []
      #从对列取出线程并开始线程,直到队列为空
      while q.empty()!=True:
        t = q.get()
        join_thread.append(t)
        t.start()
      #终止上一次队满时里面的所有线程
      for t in join_thread:
        t.join()
  end = time.time() - start
  print(end)

程序备注应该还算比较清晰的哈,程序执行结果:

python使用多线程查询数据库的实现示例

四.结论:

看结果说话

到此这篇关于python使用多线程查询数据库的实现示例的文章就介绍到这了,更多相关python 多线程查询数据库内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python的Flask框架中配置多个子域名的方法讲解
Jun 07 Python
使用Python生成XML的方法实例
Mar 21 Python
Python操作MongoDB详解及实例
May 18 Python
python编写暴力破解zip文档程序的实例讲解
Apr 24 Python
windows下cx_Freeze生成Python可执行程序的详细步骤
Oct 09 Python
在python 中实现运行多条shell命令
Jan 07 Python
python实现将文件夹内的每张图片批量分割成多张
Jul 22 Python
使用Python自动生成HTML的方法示例
Aug 06 Python
Python自动化完成tb喵币任务的操作方法
Oct 30 Python
Python关于反射的实例代码分享
Feb 20 Python
如何基于Django实现上下文章跳转
Sep 16 Python
解决virtualenv -p python3 venv报错的问题
Feb 05 Python
python使用建议与技巧分享(一)
Aug 17 #Python
Python2.6版本pip安装步骤解析
Aug 17 #Python
python中pathlib模块的基本用法与总结
Aug 17 #Python
Pycharm无法打开双击没反应的问题及解决方案
Aug 17 #Python
详解python datetime模块
Aug 17 #Python
python实现梯度下降算法的实例详解
Aug 17 #Python
python3.5的包存放的具体路径
Aug 16 #Python
You might like
Body是什么,该怎么喝出咖啡里的口感
2021/03/03 咖啡文化
PHP strtr() 函数使用说明
2008/11/21 PHP
php实现的百度搜索某地天气的小偷代码
2014/04/23 PHP
php+MySQL判断update语句是否执行成功的方法
2014/08/28 PHP
使用phpstorm和xdebug实现远程调试的方法
2015/12/29 PHP
PHP使用FFmpeg获取视频播放总时长与码率等信息
2016/09/13 PHP
PHP类的特性实例分析
2016/09/28 PHP
【消息提示组件】,兼容IE6/7&&FF2
2007/09/04 Javascript
js 刷新页面的代码小结 推荐
2010/04/02 Javascript
JavaScript 对任意元素,自定义右键菜单的实现方法
2013/05/08 Javascript
JavaScript/Js脚本处理html元素的自定义属性解析(亲测兼容Firefox与IE)
2013/11/25 Javascript
Javascript实现滚动图片新闻的实例代码
2013/11/27 Javascript
jQuery学习笔记之jQuery构建函数的7种方法
2014/06/03 Javascript
Javascript前端UI框架Kit使用指南之kitjs的对话框组件
2014/11/28 Javascript
轻松实现javascript数据双向绑定
2015/11/11 Javascript
jQuery实现的简单提示信息插件
2015/12/08 Javascript
基于canvas实现的钟摆效果完整实例
2016/01/26 Javascript
js去字符串前后空格的实现方法
2016/02/26 Javascript
基于RequireJS和JQuery的模块化编程日常问题解析
2016/04/14 Javascript
JS触发服务器控件的单击事件(详解)
2016/08/06 Javascript
在localStorage中存储对象数组并读取的方法
2016/09/24 Javascript
微信js-sdk界面操作接口用法示例
2016/10/12 Javascript
webpack打包单页面如何引用的js
2017/06/07 Javascript
JS 使用 window对象的print方法实现分页打印功能
2018/05/16 Javascript
vue 解决移动端弹出键盘导致页面fixed布局错乱的问题
2019/11/06 Javascript
[09:34]2018DOTA2国际邀请赛寻真——永不放弃的iG
2018/08/14 DOTA
Python中的rfind()方法使用详解
2015/05/19 Python
在Python的Django框架的视图中使用Session的方法
2015/07/23 Python
详解Python中最难理解的点-装饰器
2017/04/03 Python
彻底搞懂 python 中文乱码问题(深入分析)
2020/02/28 Python
纯CSS实现预加载动画效果
2017/09/06 HTML / CSS
浅析与CSS3的loading动画加载相关的transition优化
2015/05/18 HTML / CSS
蟋蟀的住宅教学反思
2014/04/26 职场文书
采购内勤岗位职责
2015/04/13 职场文书
二审答辩状范文
2015/05/22 职场文书
公安干警正风肃纪心得体会
2016/01/15 职场文书