mysql - SQLServer pyodbc 的 Python 驱动程序比 psycopg2 和带有插入的 mysql.connector 慢得多
问题描述
我们有一个用 Python 构建的应用程序,它必须在不同的数据库上运行,例如 SQLServer、MySQL 和 Postgres。当我们使用 pyodbc 库插入 SQL Server 时,这比使用 psycopg2 插入 Postgres 或使用 mysql.connector 插入 MySQL 要慢得多(20 倍!)。我有两个问题: 1. 造成这种性能差异的原因是什么?2. 我们能做什么(除了使用 Postgres/MySQL)?
解决方案
当 MySQL 连接器/Python 遇到executemany
对 INSERT 语句的调用时,它会构造一个或多个多行 INSERT,从而减少到服务器的往返次数。例如,
crsr = cnxn.cursor()
sql = "INSERT INTO mytable (id) VALUES (%s)"
params = [(x,) for x in range(3)]
crsr.executemany(sql, params)
向 MySQL 服务器发送一条 INSERT 语句
INSERT INTO mytable (id) VALUES (0),(1),(2)
相比之下,pyodbc 的默认行为是发送单独的 INSERT 语句,因此
crsr = cnxn.cursor()
sql = "INSERT INTO mytable (id) VALUES (?)"
params = [(x,) for x in range(3)]
crsr.executemany(sql, params)
发送相当于
INSERT INTO mytable (id) VALUES (0)
INSERT INTO mytable (id) VALUES (1)
INSERT INTO mytable (id) VALUES (2)
需要三次往返服务器而不是一次。
幸运的是,当前版本的 pyodbc 支持通过 Cursor 对象的fast_executemany属性对 SQL Server 进行多行 INSERT ,因此
crsr = cnxn.cursor()
sql = "INSERT INTO mytable (id) VALUES (?)"
params = [(x,) for x in range(3)]
crsr.fast_executemany = True
crsr.executemany(sql, params)
产生与上面的 MySQL 连接器/Python 示例基本相同的结果。
推荐阅读
- angularjs - Chrome 的调试器:无法使用附加选项进行调试
- sql - 在 Presto 中拆分并返回除第一个元素之外的所有元素
- python - 使用 SSL 的 manage.py runserver 0:8000
- powerbi - Power BI Desktop 中传入订单和已完成订单的比较
- python - 分类已经找到中心的字符串,python
- tfs - SonarQube 分析中不存在文件
- unity3d - Unity3D 播放器错误“接收未处理的 NULL 异常已获得 22 个堆栈帧。”
- maven - 如何在 JavaFX 应用程序中使用 Spring Boot 构建插件
- database - 在数据库级别实现“系统用户”的最佳方式(如最佳实践)是什么?
- python - Python @property setter 中的约束未应用