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基础教程之基本数据类型和变量声明介绍
Aug 29 Python
python实现稀疏矩阵示例代码
Jun 09 Python
Python基于回溯法子集树模板解决野人与传教士问题示例
Sep 11 Python
Python+Selenium+PIL+Tesseract自动识别验证码进行一键登录
Sep 20 Python
利用Python脚本批量生成SQL语句
Mar 04 Python
Python多进程编程常用方法解析
Mar 26 Python
python中for in的用法详解
Apr 17 Python
python 如何将office文件转换为PDF
Sep 22 Python
使用Python画了一棵圣诞树的实例代码
Nov 27 Python
Python实现我的世界小游戏源代码
Mar 02 Python
Python连续赋值需要注意的一些问题
Jun 03 Python
浅谈Python3中datetime不同时区转换介绍与踩坑
Aug 02 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 win下Socket方式发邮件类
2009/08/21 PHP
php中常用字符串处理代码片段整理
2011/11/07 PHP
php动态函数调用方法
2015/05/21 PHP
PHP 前加at符合@的作用解析
2015/07/31 PHP
php 广告点击统计代码(php+mysql)
2018/02/21 PHP
PHP7变量处理机制修改
2021/03/09 PHP
统计出现最多的字符次数的js代码
2010/12/03 Javascript
JSDoc 介绍使用规范JsDoc的使用介绍
2011/02/12 Javascript
jquery如何实现在加载完iframe的内容后再进行操作
2013/09/10 Javascript
js日期相关函数总结分享
2013/10/15 Javascript
js简单实现删除记录时的提示效果
2013/12/05 Javascript
jQuery判断复选框是否勾选的原理及示例
2014/05/21 Javascript
JavaScript中的slice()方法使用详解
2015/06/06 Javascript
JS+DIV+CSS实现的经典标签切换效果代码
2015/09/14 Javascript
jQuery实现Select左右复制移动内容
2016/08/05 Javascript
基于es6三点运算符的使用方法(实例讲解)
2017/10/12 Javascript
vue+vuex+axios实现登录、注册页权限拦截
2018/03/09 Javascript
JavaScript+Canvas实现彩色图片转换成黑白图片的方法分析
2018/07/31 Javascript
在vue中多次调用同一个定义全局变量的实例
2018/09/25 Javascript
Vue Cli3 打包配置并自动忽略console.log语句的方法
2020/04/23 Javascript
解决vue一个页面中复用同一个echarts组件的问题
2020/07/19 Javascript
解决VUE项目使用Element-ui 下拉组件的验证失效问题
2020/11/07 Javascript
关于uniApp editor微信滑动问题
2021/01/15 Javascript
Python黑帽编程 3.4 跨越VLAN详解
2016/09/28 Python
浅谈python正则的常用方法 覆盖范围70%以上
2018/03/14 Python
opencv3/C++实现视频背景去除建模(BSM)
2019/12/11 Python
Python获取、格式化当前时间日期的方法
2020/02/10 Python
Django ModelForm组件原理及用法详解
2020/10/12 Python
python如何调用php文件中的函数详解
2020/12/29 Python
css3中flex布局宽度不生效的解决
2020/12/09 HTML / CSS
银行工作检查书范文
2014/01/31 职场文书
幼儿园教师节活动方案
2014/02/02 职场文书
两只小狮子教学反思
2014/02/05 职场文书
年度献血先进个人事迹材料
2014/02/14 职场文书
优秀共产党员事迹材料2016
2016/02/29 职场文书
Nginx报错104:Connection reset by peer问题的解决及分析
2022/07/23 Servers