cursor.execute() with many bound parameters (~2000) is ~14x slower than pyodbc
维护者通常 2 天内回复
评估
这个 Issue 还没有评估数据。
描述
Describe the bug
When executing a multi-row INSERT with ~2000 bound parameters (the kind SQLAlchemy's insertmanyvalues generates), cursor.execute() is about 14x slower than the equivalent call through pyodbc.
cursor.executemany() is much closer between drivers (~1.6x), so the issue is specific to single cursor.execute() calls with large parameter counts.
To reproduce
import time
import mssql_python
import pyodbc
N = 100_000
COLS = 2
# ~1049 rows per INSERT, ~2098 params per call, ~95 calls total
ROWS_PER_BATCH = 2099 // COLS
SQL = "INSERT INTO bench (id, name) VALUES " + ",".join(
[f"(?, ?)"] * ROWS_PER_BATCH
)
PARAMS = [None] * (ROWS_PER_BATCH * COLS)
# --- mssql-python ---
conn = mssql_python.connect(
"SERVER=localhost;DATABASE=master;UID=sa;PWD=YourPassword;"
"Encrypt=yes;TrustServerCertificate=yes;"
)
cursor = conn.cursor()
cursor.execute(
"IF OBJECT_ID('bench') IS NOT NULL DROP TABLE bench;"
"CREATE TABLE bench (id INT, name VARCHAR(50))"
)
conn.commit()
t0 = time.perf_counter()
for _ in range(N // ROWS_PER_BATCH):
cursor.execute(SQL, PARAMS)
conn.commit()
ms_time = time.perf_counter() - t0
cursor.close()
conn.close()
# --- pyodbc ---
conn2 = pyodbc.connect(
"DRIVER={ODBC Driver 18 for SQL Server};"
"SERVER=localhost;DATABASE=master;UID=sa;PWD=YourPassword;"
"Encrypt=yes;TrustServerCertificate=yes;"
)
cursor2 = conn2.cursor()
cursor2.execute("TRUNCATE TABLE bench")
conn2.commit()
t0 = time.perf_counter()
for _ in range(N // ROWS_PER_BATCH):
cursor2.execute(SQL, PARAMS)
conn2.commit()
py_time = time.perf_counter() - t0
cursor2.close()
conn2.close()
print(f"mssql-python: {ms_time:.2f}s ({N / ms_time:,.0f} rows/s)")
print(f"pyodbc: {py_time:.2f}s ({N / py_time:,.0f} rows/s)")
Output
mssql-python: 11.87s (8,427 rows/s)
pyodbc: 0.77s (130,000 rows/s)
Context
This came up while working on SQLAlchemy integration. SA 2.x uses insertmanyvalues by default, which generates batched multi-row INSERTs with ~2098 parameters per call (limited by SQL Server's 2100 parameter cap).
For reference, cursor.executemany() is much faster on this driver (~50K rows/s) and cursor.bulkcopy() is excellent (~390K rows/s). It's really just the many-parameter cursor.execute() path that's slow.
Environment
- mssql-python: 1.4.0
- pyodbc: 5.2.0
- SQL Server: 2022
- Python: 3.12
- OS: Ubuntu 24.04
- 主要语言
- Python
- 星标
- 478
- 派生
- 62
- 平均合并
- 3 天 19 分钟
- 30 天内合并 PR
- 28
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
microsoft/mssql-python 的其他 Issue
-
area: bulk-copy triage needed
难度 2/5 1-3 小时 新手友好度 70/100
microsoft/mssql-python#843 · 1 条评论 ·
维护者通常 2 天内回复
-
triage needed
难度 4/5 3-5 天 新手友好度 35/100
microsoft/mssql-python#846 · 1 条评论 ·
维护者通常 2 天内回复
-
macOS: encrypted connections fail after Homebrew moved the `openssl` alias to `openssl@4`可能已有人在做 @bewithgaurav 于 16 天前认领。 未关闭area: packaging-platform bug triage needed
难度 4/5 3-5 天 新手友好度 55/100
microsoft/mssql-python#826 · 2 条评论 · 已指派 1 人 ·
维护者通常 2 天内回复
-
Announcement: mssql-python is coming to Django through mssql-django 2.0可能重新可做 @bewithgaurav 于 43 天前认领,目前没有进行中的 PR。 未关闭announcement
microsoft/mssql-python#748 · 已指派 1 人 ·
维护者通常 2 天内回复
-
Connection pool can briefly exceed max_size when pooling is disabled under load可能已有人在做 @bewithgaurav 于 25 天前认领。 未关闭area: connectivity-auth bug triage done under development
难度 4/5 3-5 天 新手友好度 62/100
microsoft/mssql-python#746 · 1 条评论 · 已指派 1 人 ·
维护者通常 2 天内回复
查看 microsoft/mssql-python 的全部 Issue
相似的 Issue
-
Questions crashes on a real SQuAD2 no-answer prediction可能已有人在做 @HuaTNA 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
GST is read as Gulf Standard Time (UTC+4) instead of Guam Standard Time (UTC+10)可能已有人在做 @yang00333 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
DOI-USGS/dataretrieval-python#454 ·
维护者通常 4 天内回复
-
area:core-platform effort:S priority:P3 status:in-review type:test
难度 2/5 1 小时以内 新手友好度 80/100
randomparity/kdive#3246 · 1 条评论 ·
维护者通常 1 天内回复
-
Requantification library converts m/z to mass with the hydrogen-atom mass instead of the proton mass未关闭bug
难度 1/5 1 小时以内 新手友好度 85/100
nf-core/metaboigniter#130 ·
维护者通常 1 天内回复
-
netbox status: needs owner type: documentation
难度 1/5 1 小时以内 新手友好度 75/100
netbox-community/netbox#23412 · 1 个 reaction ·
维护者通常 1 天内回复