mysql - 在循环查询结果时执行新的数据库查询
问题描述
我有一个相对繁重的 MySQL 选择查询,它在 25.000 行中返回 ca 150 MB 的数据。循环遍历整个数据集并执行所需的操作,大约需要 45 分钟。
对于一些记录(少于 10 条),我需要在同一个数据库中执行另一次查找。
如果我这样编写 Python 3 代码:
con = mysql.connection.connect( host='...', user='...', password='...', database='...' )
cursor = con.cursor( dictionary=True, buffered=True )
cursor.execute('SELECT ...')
for row in cursor:
# processing data ...
if row['...'] == ...:
cursor2 = con.cursor()
cursor2.execute('SELECT ...')
some_var = cursor2.fetch_one()[0]
# more processing...
然后,在第二次执行时cursor2
,我得到:
mysql.connector.errors.OperationalError: MySQL Connection not available.
cursor2
如果我在循环之前初始化:
con = mysql.connection.connect( host='...', user='...', password='...', database='...' )
cursor = con.cursor( dictionary=True, buffered=True )
cursor2 = con.cursor()
cursor.execute('SELECT ...')
for row in cursor:
# processing data ...
if row['...'] == ...:
cursor2.execute('SELECT ...')
some_var = cursor2.fetch_one()[0]
# more processing...
然后,在第二次执行时,我得到:
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
我不确定这些错误是由超时引起的,还是由我对多个游标的错误处理引起的。
如果有帮助,这些是我的数据库的超时设置:
connect_timeout 10
deadlock_timeout_long 50000000
deadlock_timeout_short 10000
delayed_insert_timeout 300
idle_readonly_transaction_timeout 0
idle_transaction_timeout 0
idle_write_transaction_timeout 0
innodb_flush_log_at_timeout 1
innodb_lock_wait_timeout 50
innodb_rollback_on_timeout OFF
interactive_timeout 28800
lock_wait_timeout 86400
net_read_timeout 30
net_write_timeout 60
rpl_semi_sync_master_timeout 10000
rpl_semi_sync_slave_kill_conn_timeout 5
slave_net_timeout 60
thread_pool_idle_timeout 60
wait_timeout 420
我应该如何编写此代码?这只是我的第二个 Python 脚本,所以请在初学者级别制定任何帮助。
解决方案
事实证明,连接的行为与我的预期有些不同。@Mike67 的评论指出了正确的方向,我只是遗漏了一些细节。解决方案是在每次需要新查询时创建和销毁新连接。
con = mysql.connection.connect( host='...', user='...', password='...', database='...' )
cursor = con.cursor( dictionary=True, buffered=True )
cursor.execute('SELECT ...')
for row in cursor:
# processing data ...
if row['...'] == ...:
con2 = mysql.connection.connect( host='...', user='...', password='...', database='...' )
cursor2 = con2.cursor()
cursor2.execute('SELECT ...')
some_var = cursor2.fetch_one()[0]
cursor2.close()
con2.close()
# more processing...
我觉得必须有一种更有效的方法来做到这一点,但这很有效。
推荐阅读
- c++ - 从私有成员类派生的模板类打破了封装
- c# - 我在编辑个人资料部分有一个详细信息视图。用户应该能够编辑他的个人资料并保存更改
- sql - 如果一个表有一个未索引列与索引列是一对多关系,如何优化未索引列的查询?
- mysql - 如何从 sql 转储文件升级 mariadb?
- node.js - 我想安装最新版本的nodejs
- android - Android YouTubePlayer SDK API onFullScreen 回调导致 RecyclerView ViewHolder 分离
- r - R在轴线处打破线型规则
- dynamics-crm - Dynamics 365 插件注册工具提供权限错误
- k6 - PFX 证书中的关键值是什么
- ios - 可编码为具有 nil 值键的字典