In continuation of
SqlAlchemy+pymssql. Will raw parametrized queries use same execution plan?
I switched from pymssql to pyodbc tried to get parametrized
I did a bit of testing and you need not be concerned. pyodbc only sends a single sp_unprepare
(for the last sp_prepexec
executed) when the cursor
object is closed. That is, it does not sp_unprepare
every sp_prepexec
that it sends.
Furthermore, actual timing tests reveal the difference in performance between pyodbc (which apparently can take advantage of cached execution plans) and pymssql (which apparently cannot). With the following code ...
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
the four (4) nested for
loops run a total of 10,000 queries. On my Windows test machine with a local SQL Server instance, pymssql takes about 130 seconds (just over 2 minutes) to execute, while pyodbc consistently runs the same code in under 5 seconds.