python - pyodbc 在 sp_prepexec 之后调用 sp_unprepare。这会影响参数化查询的性能吗?

标签 python sql-server sqlalchemy pyodbc

继续

SqlAlchemy+pymssql. Will raw parametrized queries use same execution plan?

我从 pymssql 切换到 pyodbc 试图将参数化查询发送到 SQL Server。带有 Microsoft 驱动程序的 pyodbc 可以解决问题,但我觉得有些奇怪:

declare @p1 int
set @p1=6
exec sp_prepexec @p1 output,N'@P1 nvarchar(6),@P2 bigint,@P3 bigint,@P4 bigint',N'
                SELECT *
                FROM CC_sold
                WHERE id_contract =@P1
                    AND id_tip_cont=@P2
                    AND CC_sold.anul =@P3
                    AND CC_sold.luna =@P4
                ORDER BY CC_sold.anul, CC_sold.luna DESC
            ',N'176914',6,2016,9
select @p1
exec sp_unprepare 6

我的担心与此声明有关:

exec sp_unprepare 6

如果我理解正确,这将取消查询执行计划,并且我不会从查询参数化中获得任何优化。是这样吗?

最佳答案

我做了一些测试,您不必担心。当 cursor 对象关闭时,pyodbc 仅发送一个 sp_unprepare(针对最后执行的 sp_prepexec)。也就是说,它不会 sp_unprepare every sp_prepexec 它发送。

此外,实际的计时测试揭示了 pyodbc(显然可以利用缓存的执行计划)和 pymssql(显然不能)之间的性能差异。使用以下代码...

crsr = conn.cursor()
crsr.execute("DBCC FREEPROCCACHE")
if 'pyodbc' in repr(conn):
    sql = "SELECT COUNT(*) AS n FROM table1 WHERE cola=? AND colb=? AND colc=? AND cold=?"
else:
    sql = "SELECT COUNT(*) AS n FROM table1 WHERE cola=%s AND colb=%s AND colc=%s AND cold=%s"
t0 = time.time()
limit = 10
for a in range(limit):
    for b in range(limit):
        for c in range(limit):
            for d in range(limit):
                params = (a, b, c, d)
                crsr.execute(sql, params)
                n = crsr.fetchone()[0]
print(time.time() - t0)
crsr.close()
conn.close()

... for limit = 10 四 (4) 个嵌套 for 循环总共运行 10,000 个查询。在我的带有本地 SQL Server 实例的 Windows 测试机器上,pymssql 需要大约 130 秒(刚好超过 2 分钟)来执行,而 pyodbc 始终在 5 秒内运行相同的代码。

关于python - pyodbc 在 sp_prepexec 之后调用 sp_unprepare。这会影响参数化查询的性能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40131336/

相关文章:

c# - Azure Linux ASP 上运行的 .net core 与 Azure SQL 数据库之间的连接池问题

python - PostgreSQL 从文件中复制导致空表

sql - 如何在 sqlalchemy 中生成此查询?

python - 统一码编码错误 : 'mbcs' codec can't encode characters in position 0--1: invalid character upon running a PyInstaller-compiled script

python - "eval"和 "int"有什么区别

python - Django:TemplateDoesNotExist 在/home.html

sql-server - 如何重新索引 AuditLog 表?非聚簇主键、聚簇覆盖索引、GUID

python pandas 绘制两个数据,但在直方图上只显示一个

sql-server - 如何使用 TSQL 截断数据库中的所有表?

python - SQLAlchemy:相同的表但不同的数据库引擎