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删除java文件头上版权信息的方法
Jul 31 Python
Django中对数据查询结果进行排序的方法
Jul 17 Python
Python中数字以及算数运算符的相关使用
Oct 12 Python
windows 10下安装搭建django1.10.3和Apache2.4的方法
Apr 05 Python
Python Flask基础教程示例代码
Feb 07 Python
python 将数据保存为excel的xls格式(实例讲解)
May 03 Python
python安装requests库的实例代码
Jun 25 Python
python文件和文件夹复制函数
Feb 07 Python
pyCharm 实现关闭代码检查
Jun 09 Python
python3.6.8 + pycharm + PyQt5 环境搭建的图文教程
Jun 11 Python
keras的load_model实现加载含有参数的自定义模型
Jun 22 Python
解决hive中导入text文件遇到的坑
Apr 07 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函数method_exists()与is_callable()的区别
2013/06/21 PHP
php构造函数实例讲解
2013/11/13 PHP
基于PHP-FPM进程池探秘
2017/10/17 PHP
Yii 框架控制器创建使用及控制器响应操作示例
2019/10/14 PHP
Laravel5.5+ 使用API Resources快速输出自定义JSON方法详解
2020/04/06 PHP
Riot.js 快速的JavaScript单元测试框架
2009/11/09 Javascript
网页源代码保护(禁止右键、复制、另存为、查看源文件)
2012/05/23 Javascript
高效的获取当前元素是父元素的第几个子元素
2013/10/15 Javascript
jquery live()调用不存在的解决方法
2014/02/26 Javascript
jQuery stop()用法实例详解
2016/07/28 Javascript
js调用父框架函数与弹窗调用父页面函数的简单方法
2016/11/01 Javascript
详解React开发中使用require.ensure()按需加载ES6组件
2017/05/12 Javascript
Vue使用vue-cli创建项目
2017/09/01 Javascript
微信小程序事件对象中e.target和e.currentTarget的区别详解
2019/05/08 Javascript
浅谈js中的attributes和Attribute的用法与区别
2020/07/16 Javascript
一文读懂vue动态属性数据绑定(v-bind指令)
2020/07/20 Javascript
[00:58]2016年国际邀请赛勇士令状宣传片
2016/06/01 DOTA
[01:21]DOTA2周边文化主题展 神秘商店火热开售
2017/07/30 DOTA
跟老齐学Python之关于循环的小伎俩
2014/10/02 Python
Python之Scrapy爬虫框架安装及简单使用详解
2017/12/22 Python
使用python来调用CAN通讯的DLL实现方法
2019/07/03 Python
python使用 request 发送表单数据操作示例
2019/09/25 Python
pytorch多GPU并行运算的实现
2019/09/27 Python
基于python实现语音录入识别代码实例
2020/01/17 Python
python利用后缀表达式实现计算器功能
2021/02/22 Python
北美领先的牛仔品牌:Buffalo David Bitton
2017/05/22 全球购物
MADE荷兰:提供原创设计师家具
2018/04/03 全球购物
大学生最常用的自我评价
2013/12/07 职场文书
预备党员政审材料
2014/02/04 职场文书
捐赠仪式主持词
2014/03/19 职场文书
如何撰写一封出色的求职信
2014/04/27 职场文书
反邪教警示教育方案
2014/05/13 职场文书
企业优秀员工事迹材料
2014/05/28 职场文书
医德医风自我评价
2014/09/19 职场文书
卫生厅领导班子党的群众路线教育实践活动整改措施
2014/09/20 职场文书
如何写观后感
2015/06/19 职场文书