Правильно ли реализовано связывание параметров в библиотеке pymssql?
Я вызываю чрезвычайно простой запрос из программы Python с использованием библиотеки pymsqsql.
with self.conn.cursor() as cursor:
cursor.execute('select extra_id from mytable where id = %d', id)
extra_id = cursor.fetchone()[0]
Обратите внимание, что привязка параметров используется, как описано в документации по pymssql.
Одной из основных целей привязки параметров является предоставление ядру СУБД возможности кэшировать план запроса. Я подключился к MS SQL с помощью Profiler и проверил, какие запросы фактически выполняются. Оказалось, что каждый раз, когда выполняется уникальный оператор (со своим связанным идентификатором). Я также проверил использование запроса с таким запросом:
select * from sys.dm_exec_cached_plans ec
cross apply
sys.dm_exec_sql_text(ec.plan_handle) txt
where txt.text like '%select extra_id from mytable where id%'
И это показало, что план не используется повторно (что, конечно, можно ожидать благодаря уникальному тексту каждого запроса). Это сильно отличается от привязки параметров при запросах из C#, когда мы видим, что запросы одинаковы, но предоставленные параметры отличаются.
Поэтому мне интересно, правильно ли я использую pymssql и подходит ли эта библиотека для использования с СУБД MS SQL.
PS Я знаю, что MS SQL имеет функцию автопараметризации, которая работает для базовых запросов, но это не гарантируется и может не работать для сложных запросов.
1 ответ
Вы используете pymssql правильно. Это правда, что pymssql на самом деле подставляет значения параметров в текст SQL перед отправкой запроса на сервер. Например:
pymssql:
SELECT * FROM tablename WHERE id=1
pyodbc с драйвером ODBC от Microsoft для SQL Server (не драйвер ODBC для FreeTDS):
exec sp_prepexec @p1 output,N'@P1 int',N'SELECT * FROM tablename WHERE id=@P1',1
Однако имейте в виду, что pymssql основан на FreeTDS, и описанное выше поведение, по-видимому, является функцией способа, которым FreeTDS обрабатывает параметризованные запросы, а не специфической особенностью pymssql как таковой.
И да, это может иметь последствия для повторного использования планов выполнения (и, следовательно, производительности), как показано в этом ответе.