有一个 while 循环业务,每 10 分钟去请求一下,发现有数据更新了,就抓过来存到 MySQL 中去。
import MySQLdb
db = MySQLdb.connect(host='localhost', port=3306, user='xxx', passwd='xxx', db='xxx_DB', charset='utf8')
cursor = db.cursor()
# do something...
db.commit()
1、如果没有 db.close(),多长时间之后,这次连接会自动 close 掉?
2、如果不执行 db.close(),因为是个 while 循环,是不是每次都会重新建立一个 db 连接?
3、如果每次都执行 db.close(),那么下次又要重新建立连接,这样性能有多大损耗?
1
CallMeReznov 2019-03-21 23:07:50 +08:00 12
啊...看到楼主的问题仿佛遇到了 5 年前的自己.
1.超时时间设置 2.连接数一般是有限的,你只建立不释放的后果就是在超时时间内达到最大连接数会导致你无法继续 3.比起上面两个造成的问题,建立-执行-关闭,这都属于正常的负载范围,如果你的数据库载体这点操作都无法顺利进行你就地想办法优化提升你的服务器处理能力或者优化你的 SQL 语句了 |
2
Northxw 2019-03-22 00:21:11 +08:00 6
额,仿佛看到大二的自己...
简单来说,构造一个数据库的类,在__init__中初始化,在__del___中自动关闭数据库连接,再设置一个只进行插入操作的函数。 最后生成一个类的实例,While 定时循环调用实例中插入操作函数,应该就 OJBK 了。大概这样: class Save(object): def __init__(self): self.localhost = 'localhost' self.user= 'root' # 或者其他 self.pass_ = 'xxxx' self.port= 3306 self.db= 'database_name' def __del__(self): self.db.close() def save(self): pass if main == '........'(忘了): save_mysql = Save() while True: save_mysql.save() |
3
hcymk2 2019-03-22 00:30:20 +08:00 via Android 2
用链接池
|
4
zjp 2019-03-22 00:42:05 +08:00 via Android 4
同仿佛大二的自己…
MySQL 会自动关闭空闲 8 小时的连接,这个时间由 wait_timeout 配置。貌似多数数据库不会自动关闭 3. 一般程序都会用连接池,不过 10 分钟才一次的随便了……毕竟有些连接池默认 30 分钟也会全部重新连接或者直接 close |
5
kernel 2019-03-22 06:36:52 +08:00 via Android
10 分钟一次就重新连就行了。你想想很早以前用 PHP 写网页,每一个请求都重新连一下,你这 10 分钟一次频率算个鸟。
|
6
ericgui 2019-03-22 06:49:35 +08:00 5
|
7
ericgui 2019-03-22 06:50:21 +08:00
|
8
fngtz 2019-03-22 08:28:05 +08:00 via iPhone
@Northxw python 一般不用 del。需要 clos 的对象 e 可以用上下文( enter,exit )。
|
9
Torpedo 2019-03-22 08:54:47 +08:00 via Android
这个帖子好和谐
|
10
Sothoth 2019-03-22 09:01:23 +08:00
加个装饰器
|
12
coolair 2019-03-22 09:11:12 +08:00 via Android
如果是循环插数据,可以先把数据放列表,然后一次插入多条数据,如果数据量大,可以设置一个长度,比如 500 条写一次数据库。
|
13
David1119 2019-03-22 09:15:56 +08:00
推荐直接使用 sqlalchemy 的连接池,性能很好,可以用 orm,也可以直接用 raw sql。
另外 django 遇到高并发问题性能不行,用 sqlalchemy 替代原来的 connection 并加上连接池,性能翻倍。 |
14
zuoakang 2019-03-22 09:19:15 +08:00 via Android
连接池有用
|
15
ctro15547 2019-03-22 09:28:58 +08:00
刚开始学的话可以不停重连关闭没关系,用学校的电脑数据库一般处理能力每秒几千莫得问题,可以不用担心性能问题
|
16
inhzus 2019-03-22 09:29:20 +08:00 via Android
一定要记得 close 的。去年有个大一的学弟一起做个项目,好好的突然怎么都不能连接数据库。后来查日志发现他代码全部都是只管 connect 不管 close,超过最大连接数就凉凉。
|
17
dnsaq 2019-03-22 09:32:20 +08:00 via iPhone
首先不要想着 mysql 自动帮你关闭因为实际没有屁用甚至会把业务搞崩,自己骗自己,严格要求自己 colse 或者连接池,我公司的程序天天报超出 max con 还找运维的问题
|
18
wly19960911 2019-03-22 09:38:39 +08:00
连接池管理 sql 的连接 ,连接池会保持几条连接,并且根据并发会新开到一定限制数量的连接,然后会自己关闭,你只需要从连接池拿连接就好,自己不用创建连接。
|
19
Nicoco 2019-03-22 09:46:13 +08:00
SQLAlchemy 值得选择
|
20
suueyoung 2019-03-22 09:52:30 +08:00
with statement
|
21
fngtz 2019-03-22 09:59:59 +08:00
|
23
qq976739120 2019-03-22 10:17:15 +08:00
用链接池也要 close 的.....
|
24
wuyue92tree 2019-03-22 11:49:01 +08:00
连接池 + 单例模式建立 mysql 对象
不 close,时间久了,TCP 链接会多到爆,性能杀手 |
26
aploium 2019-03-22 13:39:26 +08:00
可以用 sqlalchemy 自带的连接池, 如
engine=sqlalchemy.create_engine(DB_URL) result_proxy=engine.execute('some sql') rows=result_proxy.fetchall() 不用专门去考虑连接池和释放的问题, 里面内置了 |
27
1762628386 2019-03-22 15:15:26 +08:00
啊...看到楼主的问题仿佛遇到了 4 年前的自己.
换个思路,只去判断是否抓取即刻,10 分钟的定时交给外部命令:crontab supervise,做好进程监控。 |
28
hayi 2019-03-22 15:38:48 +08:00
torndb 模块可以解决
|
29
Vegetable 2019-03-22 16:08:46 +08:00 1
我...不回忆能回答问题吗?
我举个例子 比如我想上厕所需要纸 纸是公司提供的,放在行政那里 好,现在问题变了: 我上厕所用完纸需要每次都给让行政拿回去吗? 正常情况下,还与不还都无所谓,因为你不叫她过来拿,过了 8 小时(默认可配置)不用的话行政小妹会自己从我兜里拿走. 有些程序没处理这情况,以为自己有纸,就出现了裤子都脱了最后发现:"卧槽我纸呢?!"程序报错(2006 gone away). 所以如果不是特别高的负载,就还回去好了. 那么如果负载特别高呢?比如拉肚子了一天去很多次,还来还去的太麻烦了,耽误事憋不住不就完了吗? 这情况能不还就不还了,影响性能. 离得近的几个人成立了一个小组共同保管 3 包纸(连接池),同时有一个小弟负责和行政沟通纸的一切事宜,那么组里别人就不用管纸的事情了,一伸手就肯定有. 所以没什么标准答案,合适就好.最简单就是每次都重新打开一个,用完关了.建议从这个方案开始 |
30
Raymon111111 2019-03-22 16:22:46 +08:00
用连接池, 不要自己管理这个.
如果是学习的目的可以仔细研究研究. |
31
boxvivi007 2019-03-22 20:00:37 +08:00
为什么不用 with 语句自动管理上下文
|