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操作sqlite的CRUD实例分析
May 08 Python
python2.7 json 转换日期的处理的示例
Mar 07 Python
python对离散变量的one-hot编码方法
Jul 11 Python
Linux下python3.6.1环境配置教程
Sep 26 Python
python保存二维数组到txt文件中的方法
Nov 15 Python
Python爬取数据保存为Json格式的代码示例
Apr 09 Python
python matplotlib饼状图参数及用法解析
Nov 04 Python
PyTorch 对应点相乘、矩阵相乘实例
Dec 27 Python
Python函数式编程实例详解
Jan 17 Python
新手学习Python2和Python3中print不同的用法
Jun 09 Python
如何在keras中添加自己的优化器(如adam等)
Jun 19 Python
Jupyter Notebook安装及使用方法解析
Nov 12 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
php数组中删除元素的实现代码
2012/06/22 PHP
如何用php获取程序执行的时间
2013/06/09 PHP
Javascript处理DOM元素事件实现代码
2012/05/23 Javascript
浅谈javascript六种数据类型以及特殊注意点
2013/12/20 Javascript
javascript删除数组元素并且数组长度减小的简单实例
2014/02/14 Javascript
JavaScript框架(iframe)操作总结
2014/04/16 Javascript
JavaScript生成福利彩票双色球号码
2015/05/15 Javascript
jQuery实现文件上传进度条特效
2015/08/12 Javascript
js实现适配不同的屏幕大小
2017/04/10 Javascript
JavaScript数据结构中串的表示与应用实例
2017/04/12 Javascript
thinkjs 文件上传功能实例代码
2017/11/08 Javascript
浅谈用Webpack路径压缩图片上传尺寸获取的问题
2018/02/22 Javascript
jQuery移动端跑马灯抽奖特效升级版(抽奖概率固定)实现方法
2019/01/18 jQuery
Vue+axios+WebApi+NPOI导出Excel文件实例方法
2019/06/05 Javascript
layui内置模块layim发送图片添加加载动画的方法
2019/09/23 Javascript
vue-drag-chart 拖动/缩放图表组件的实例代码
2020/04/10 Javascript
js实现点击选项置顶动画效果
2020/08/25 Javascript
[00:35]2016完美“圣”典风云人物:冷冷宣传片
2016/12/08 DOTA
在Python中使用判断语句和循环的教程
2015/04/25 Python
使用Python制作微信跳一跳辅助
2018/01/31 Python
python学习笔记--将python源文件打包成exe文件(pyinstaller)
2018/05/26 Python
Anaconda 离线安装 python 包的操作方法
2018/06/11 Python
在mac下查找python包存放路径site-packages的实现方法
2018/11/06 Python
PyCharm2020.1.2社区版安装,配置及使用教程详解(Windows)
2020/08/07 Python
OpenCV+python实现膨胀和腐蚀的示例
2020/12/21 Python
html5 canvas fillRect坐标和大小的问题解决方法
2014/03/26 HTML / CSS
澳洲本土太阳镜品牌:Quay Australia
2019/07/29 全球购物
应届生程序员求职信
2013/11/05 职场文书
七年级音乐教学反思
2014/01/26 职场文书
2015元旦家电促销活动策划方案
2014/12/09 职场文书
会计工作态度自我评价
2015/03/06 职场文书
2016消防宣传标语口号
2015/12/26 职场文书
描述鲁迅的名言整理,一生受用
2019/08/08 职场文书
Python使用psutil库对系统数据进行采集监控的方法
2021/08/23 Python
Java 在生活中的 10 大应用
2021/11/02 Java/Android
为Centos安装指定版本的Docker
2022/04/01 Servers