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中内置数据类型list,tuple,dict,set的区别和用法
Dec 14 Python
浅谈Python类里的__init__方法函数,Python类的构造函数
Dec 10 Python
分享6个隐藏的python功能
Dec 07 Python
Python 判断文件或目录是否存在的实例代码
Jul 19 Python
在Pycharm中将pyinstaller加入External Tools的方法
Jan 16 Python
python的移位操作实现详解
Aug 21 Python
python实现处理mysql结果输出方式
Apr 09 Python
ipython jupyter notebook中显示图像和数学公式实例
Apr 15 Python
python raise的基本使用
Sep 10 Python
Django celery异步任务实现代码示例
Nov 26 Python
解决python 执行shell命令无法获取返回值的问题
Dec 05 Python
Python函数式编程中itertools模块详解
Sep 15 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过滤输入操作之htmlentities与htmlspecialchars用法分析
2017/02/17 PHP
Laravel 6 将新增为指定队列任务设置中间件的功能
2019/08/06 PHP
Laravel如何同时连接多个数据库详解
2019/08/13 PHP
一个javascript参数的小问题
2008/03/02 Javascript
基于jquery的合并table相同单元格的插件(精简版)
2011/04/05 Javascript
javascript校验价格合法性实例(必须输入2位小数)
2014/05/05 Javascript
Three.js学习之Lamber材质和Phong材质
2016/08/04 Javascript
js中json处理总结之JSON.parse
2016/10/14 Javascript
在 Vue.js中优雅地使用全局事件的方法
2019/02/01 Javascript
Vue注册组件命名时不能用大写的原因浅析
2019/04/25 Javascript
Vue项目实现换肤功能的一种方案分析
2019/08/28 Javascript
vue中npm包全局安装和局部安装过程
2019/09/03 Javascript
详解Vue中CSS样式穿透问题
2019/09/12 Javascript
Javascript 关于基本类型和引用类型的个人理解
2019/11/01 Javascript
javascript实现商品图片放大镜
2019/11/28 Javascript
VUE异步更新DOM - 用$nextTick解决DOM视图的问题
2020/11/06 Javascript
[41:41]TFT vs Secret Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
[14:24]Optic Gaming vs PSG LGD BO3
2018/06/07 DOTA
Python break语句详解
2014/03/11 Python
Python基本语法经典教程
2016/03/11 Python
Python3.x对JSON的一些操作示例
2017/09/01 Python
MAC中PyCharm设置python3解释器
2017/12/15 Python
Python通用循环的构造方法实例分析
2018/12/19 Python
Python实现不规则图形填充的思路
2020/02/02 Python
pycharm通过ssh连接远程服务器教程
2020/02/12 Python
简单了解Python字典copy与赋值的区别
2020/09/16 Python
浅谈css3新单位vw、vh、vmin、vmax的使用详解
2017/12/01 HTML / CSS
基于HTML5新特性Mutation Observer实现编辑器的撤销和回退操作
2016/01/11 HTML / CSS
家得宝官网:The Home Depot(全球最大的家居装饰专业零售商)
2018/12/17 全球购物
学校司机岗位职责
2013/11/14 职场文书
大学生水果店创业计划书
2014/01/28 职场文书
项目合作协议书范本
2014/04/16 职场文书
安全标兵事迹材料
2014/08/17 职场文书
2014市国税局对照检查材料思想汇报
2014/09/23 职场文书
vue+elementui 实现新增和修改共用一个弹框的完整代码
2021/06/08 Vue.js
阿里云k8s服务升级时502错误 springboot项目应用
2022/04/09 Servers