SQLAlchemy+pymssql. Будут ли необработанные параметризованные запросы использовать тот же план выполнения?

В моем приложении у меня есть параметризованные запросы:

res = db_connection.execute(text("""
        SELECT * FROM Luna_gestiune WHERE id_filiala = :id_filiala AND  anul=:anul AND luna = :luna
        """), 
     id_filiala=6, anul=2010, luna=7).fetchone()

Будет ли такой запрос использовать тот же план выполнения запроса, если я буду выполнять его в цикле с разными значениями параметров?

1 ответ

Решение

Это кажется маловероятным. pymssql использует FreeTDS, а FreeTDS выполняет подстановку параметров перед отправкой запроса на сервер, в отличие от некоторых других механизмов, которые отправляют "шаблон" запроса и параметры отдельно (например, pyodbc с драйверами ODBC от Microsoft, как описано в этом ответе).

То есть для запроса, который вы описываете в своем вопросе, pymssql/FreeTDS не будет отправлять строку запроса, такую ​​как

SELECT * FROM Luna_gestiune WHERE id_filiala = @P1 AND anul = @P2 AND luna = @P3

вместе с отдельными значениями для @P1 = 6, @P2 = 2010 и т. д. Вместо этого сначала будет сконструирован литеральный запрос, а затем отправлено

SELECT * FROM Luna_gestiune WHERE id_filiala = 6 AND anul = 2010 AND luna = 7

Таким образом, для каждого параметризованного запроса, который вы отправляете, текст команды SQL будет отличаться, и я понимаю, что ядра СУБД будут повторно использовать кэшированный план выполнения, только если текущий текст команды идентичен кэшированной версии.

Редактировать: Последующее тестирование подтверждает, что pymssql, очевидно , не использует повторно кэшированные планы выполнения. Подробности в этом ответе.

Другие вопросы по тегам