2016-12-16 5 views
1

Я использую Connector/Python для вставки многих строк в таблицу temp в mysql. Строки находятся в списке списков. Я выполнить вставку, как это:Почему оптимизаторы встраивания коннектора/Python не выполняются?

cursor = connection.cursor(); 
batch = [[1, 'foo', 'bar'],[2, 'xyz', 'baz']] 
cursor.executemany('INSERT INTO temp VALUES(?, ?, ?)', batch) 
connection.commit() 

я заметил, что (со многими более строками, конечно) производительность была крайне бедна. Используя SHOW PROCESSLIST, я заметил, что каждая вставка выполнялась отдельно. Но в документации https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-executemany.html говорится, что это должно быть оптимизировано на 1 вставку. Что происходит?

+0

https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html «Этот метод выполняет задание базы данных (запрос или команду). Параметры, найденные в Параметры кортежа или словаря привязаны к переменным в операции. Укажите переменные с использованием стиля параметра% s или% (name) s (то есть с использованием формата или стиля pyformat). execute() возвращает итератор, если multi - True. " Здесь нет ? заполнитель в курсор api вообще. – pvg

+0

И все же это заявление работает на 100% штрафом с '?'. Я использовал это, потому что другие разработчики использовали его в существующем коде. Причудливо, что он работает *. – blueimpb

+0

Api сам поддерживает различные заполнители и, возможно, некоторые общие функции где-то их ловят? В любом случае, вы действительно можете запросить сама реализация для владельца места https://www.python.org/dev/peps/pep-0249/#paramstyle. В случае соединителя mysql вы всегда должны использовать% s или названный Титулы. – pvg

ответ

2

Ответ, чтобы другие люди не прошли через отладку, которую я должен был!

Я написал запрос, моделирующий его по другим запросам в нашем коде, который использовал подготовленные инструкции и использовал '?' для указания параметров. Но вы не можете это сделать для executemany()! Он должен использовать '% s'. Переход на следующее:

cursor.executemany('INSERT INTO temp VALUES(%s,%s,%s)', batch) 

... привел к улучшению скоростного сторицей и оптимизированные одного запроса можно увидеть с помощью SHOW PROCESSLIST. Остерегайтесь стандартного '?' синтаксис!

+0

В большинстве случаев вы должны использовать подготовленные инструкции, чтобы избежать SQL-инъекции. Существует множество других механизмов, встроенных в mysql для облегчения массовых вставок. В первую очередь LOAD DATA INFILE, это было бы намного быстрее, чем ваш выполнить многие – e4c5

+0

@ e4c5. Я не уверен, что плакат использовал, но% s не? является заполнитель значений для всего соединителя соединителя mysql api. – pvg

+0

Это именно то, что я говорю. Теперь я знаю, что% s является правильным заполнителем, но только потому, что '?' не был оптимизирован, а не потому, что он не работал. ? работает просто отлично. Вот что такое гигантская боль для отладки. – blueimpb

 Смежные вопросы

  • Нет связанных вопросов^_^