2016-12-16 6 views
1

私はConnector/Pythonを使用して、多くの行をmysqlの一時テーブルに挿入しています。行はすべてリストのリストにあります。私は、パフォーマンスが非常に悪かった(より多くの行を持つ、もちろん)ことに気づいConnector/Python executemanyが挿入を最適化しないのはなぜですか?

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)のパラメータスタイル(つまり、formatまたはpyformatスタイルを使用)を使用して変数を指定するexecute()は、multiがTrueの場合はイテレータを返します。いいえ?プレースホルダをカーソルAPIに配置します。 – pvg

+0

それでも、その声明は '?'で100%罰金を働かせます。他の開発者が既存のコードでそれを使用していたので、私はこれを使用しましたそれはちょっとしたことが奇妙です。 – blueimpb

+0

API自体はさまざまなプレースホルダをサポートしています。おそらくどこかの一般的な機能がそれらをキャッチしていますか?どちらの方法でも、実際にプレースホルダーの実装自体を照会することができますhttps://www.python.org/dev/peps/pep-0249/#paramstyle mysqlコネクターの場合は、常に%sまたは名前付きparams。 – pvg

答えて

2

他の人に回答すると、私はしなければならなかったデバッグを通過しません!

私は、用意されたステートメントを使用した他のクエリでモデリングしたクエリを作成し、 '?'パラメータを示す。しかし、は実行できませんexecutemany()ので '%s'を使用する必要があります。

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

... SHOW PROCESSLISTを使用すると、100倍の速度向上と最適化された単一のクエリが表示されます。標準に注意してください?構文!

+0

ほとんどの場合、SQLインジェクションを避けるためにプリペアドステートメントを使用する必要があります。一括挿入を容易にするためにmysqlに組み込まれている他の多くのメカニズムがあります。特にLOAD DATA INFILEは、多くの実行よりもはるかに高速です – e4c5

+0

@ e4c5問題のステートメントが正しく引用されています。私はポスターが何を使っていたのか分かりませんが%sはありませんか? mysqlコネクタのカーソルapi全体の値のプレースホルダです。 – pvg

+0

それはまさに私が言っていることです。 %sは正しいプレースホルダですが、 '?'最適化されていませんでした。 ?うまく動作します。それはデバッグするのに巨大な痛みです。 – blueimpb

関連する問題