Python драйвер для SQLServer pyodbc намного медленнее, чем psycopg2 и mysql.connector со вставками

0

У нас есть приложение, построенное на Python, которое должно запускаться в разных базах данных, например SQLServer, MySQL и Postgres. Когда мы вставляем в SQL Server с помощью библиотеки pyodbc, это намного медленнее (20 раз!), Чем при выполнении тех же вставок в Postgres, используя psycopg2 или в MySQL, используя mysql.connector. У меня есть два вопроса: 1. В чем причина этой разницы в производительности? 2. Что мы можем сделать (помимо использования Postgres/MySQL)?

  • 0
    По умолчанию psycopg2 отключил автокоммит. Возможно, pyodbc использует режим автоматической фиксации.
  • 0
    Привет, Павел, спасибо, но у нас также есть автокоммит в psycopg2.
Показать ещё 3 комментария
Теги:
sql-server
python-3.x
pyodbc

1 ответ

0

Когда MySQL Connector/Python встречает вызов executemany для оператора INSERT, он создает один или несколько многострочных INSERT, тем самым уменьшая количество обращений к серверу. Например,

crsr = cnxn.cursor()
sql = "INSERT INTO mytable (id) VALUES (%s)"
params = [(x,) for x in range(3)]
crsr.executemany(sql, params)

отправляет на сервер MySQL один оператор INSERT

INSERT INTO mytable (id) VALUES (0),(1),(2)

Напротив, поведение по умолчанию для pyodbc заключается в отправке отдельных инструкций INSERT, поэтому

crsr = cnxn.cursor()
sql = "INSERT INTO mytable (id) VALUES (?)"
params = [(x,) for x in range(3)]
crsr.executemany(sql, params)

отправляет эквивалент

INSERT INTO mytable (id) VALUES (0)
INSERT INTO mytable (id) VALUES (1)
INSERT INTO mytable (id) VALUES (2)

требуя трех раундов на сервере вместо одного.

К счастью, текущие версии pyodbc поддерживают многострочные INSERT на SQL Server через свойство fast_executemany объекта Cursor, поэтому

crsr = cnxn.cursor()
sql = "INSERT INTO mytable (id) VALUES (?)"
params = [(x,) for x in range(3)]
crsr.fast_executemany = True
crsr.executemany(sql, params)

дает по существу тот же результат, что и пример MySQL Connector/Python выше.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню