Python封装多条SQL语句优化性能:BEGIN...END实战与异常处理
本文介绍如何利用Python将多条SQL语句封装在BEGIN...END块中一次性提交,以减少数据库连接与网络传输开销,显著降低模型运行耗时。针对Oracle数据库唯一约束冲突(ORA-00001)问题,提供了基于字典去重并保留高权重因子的解决方案。同时补充了PostgreSQL中使用%s占位符时必须添加引号的注意事项,旨在提供高效且稳定的数据库交互方案。
Python封装多条SQL语句优化性能:BEGIN END实战
在Python中通过BEGIN...END块封装并执行多条SQL语句。
出于业务需求,需优化模型运行时间。由于每次单独执行SQL语句都需要建立连接、查询并获取数据,耗时过长,因此考虑将多条SQL语句合并提交运行,以节省大量时间。原本耗时1.6至2.5秒的SQL语句,经此方法修改后,耗时降至0.3至0.6秒,性能提升显著。
另一种思路是使用Python ORM框架,理论上可能更快,耗时几乎可忽略。但这仅为猜想,若仅为优化一个模型而引入整个框架,代码改动较大,投入产出比未必理想。未来若有时间,可尝试验证该方案。
本次优化未改动基本代码逻辑,主要利用BEGIN...END进行SQL整合。
公司使用Oracle数据库,此前未接触过,但感觉与MySQL基本类似。若使用MySQL,该方法同样适用。
sql_str = ‘begin\n' sql_str += ‘这里是需要执行的SQL语句' sql_str += ‘\ncommit;end;'
中间包含多少条SQL语句无关紧要。观察运行时间发现,一千行SQL的执行耗时几乎等同于其中耗时最长的那一条。至于异步执行或其他机制尚不清楚,核心优势在于仅建立一次连接,省去了网络传输数据和请求数据库的过程。
命令行执行BEGIN END的解决方案
网上许多关于BEGIN...END的示例仅在可视化工具中有效,无法在命令行(command)中直接执行,这意味着代码封装可能无效。幸而坚持研究找到了解决办法。
在END后提交即可解决问题。若在命令行中运行一直未结束,可添加一个斜杠(/)即可。
本次内容至此结束,以下补充一些题外话。
处理唯一约束冲突与因子重要度去重
分享一个遇到的问题:SQL封装后,涉及的表结构混乱,约束繁多且逻辑不严谨。由于模型正在运行且不允许修改底层规则,只能按现有规则处理。
遇到ORA-00001错误,即违反唯一约束条件。原因是模型输入导致处理结果可能与数据库中已存在的数据重复(即上述sql_str中出现了两次相同的INSERT语句)。解决此问题很简单,只需添加SET判断即可。但随之出现一个新Bug:该脚本计算因子重要度,预测结果每次可能不同,某些数据值较小可能被当作0处理。因此,需要在相同数据情况下插入重要度较高的因子(无需额外操作)。简单的SET无法解决此问题,但使用字典即可轻松应对。
importance_map = {}
实现创建好字典
if feature in importance_map:
if importance_map[feature] < importance:
sql_str +=‘***************‘'' 这里就是insert语句了
else:
continue
else:
importance_map[feature] = importance
内存管理与Pandas使用反思
其实该问题并无难点,但解决过程中引发了诸多思考。
数据处理本可使用Pandas,但Pandas是对所有数据进行操作,而此处仅需对重复数据进行SET操作。此外,Pandas内存消耗极大,前几日进行特征工程时内存溢出。表数据处理完毕后,内存并未释放,这涉及Python的垃圾回收机制,具体用法尚需研究。gc主要针对循环引用进行垃圾回收和内存释放,但Pandas并非循环引用,而是存储在缓冲区中,位置固定,导致内存无法释放,令人困扰。
模型在服务器上运行,务必追求快速且节省内存,否则占用过多内存会影响其他项目运行。因此采用上述方法。
很少撰写博客,主要为了记录问题,以便日后应对。若能帮助正在修复Bug的你,亦感欣慰。若有表述不清或错误之处,欢迎留言指正。
PostgreSQL使用%s占位符的注意事项
补充知识:PostgreSQL SQL中使用%s时务必添加引号,即‘%s',否则报错。
PostgreSQL SQL中使用%s时务必添加引号,即‘%s',否则报错。
if name == ‘main':
t="TDD-LTE_MRO"
sql="select * from lastftp where enbid = %d and keytype = %s"%(110001,t)
print(selectOperate(sql))
结果:
Traceback (most recent call last):
File “/home/eyann/mypython/t1/pgSQLoperate.py”, line 84, in
print(selectOperate(sql))
File “/home/eyann/mypython/t1/pgSQLoperate.py”, line 45, in selectOperate
cursor.execute(sql)
psycopg2.ProgrammingError: column “tdd” does not exist
LINE 1: …* from lastftp where enbid = 110001 and keytype = TDD-LTE_MR…
^
if name == ‘main':
t="TDD-LTE_MRO"
sql="select * from lastftp where enbid = %d and keytype = '%s'"%(110001,t)
print(selectOperate(sql))
结果:
[(‘test3', ‘TDD-LTE_MRO', ‘0114123000', ‘0012', 110001)] [Finished in 0.1s]
以上关于Python实现一次性封装多条SQL语句(BEGIN...END)的内容即为分享的全部,希望能提供参考,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













