以下に示すようなテーブルとストアド プロシージャがあります。
リーリー私は、単に挿入を呼び出すよりもストアド プロシージャを呼び出す方がはるかに高速であると考えていました。しかし驚いたことに、そうではありません。 10000 行のレコードを挿入すると、挿入コマンドには約 4 分、ストアド プロシージャには約 15 分がかかります。
これを確認するためにテストを複数回実行しました。 MySQL サーバーはハイエンドサーバーではありませんが、ストアドプロシージャの呼び出しがなぜこれほど遅いのか理解できません。
リーリー ところで、挿入速度を上げるために innodb_flush_log_at_trx_commit = 2
を設定できるという記事をいくつか読みましたが、私はそんなつもりはありません。
---更新---
得られた回答に基づいて、バッチ挿入 (executemany
) を実行して改善があるかどうかを確認しましたが、驚いたことに、 はありませんでした。
リーリー
executemany 100 レコードの 1 ショットも試しました)、パフォーマンスは基本的に同じであることがわかりました。
###何故ですか?
--- アップデート 2 ---
挿入が遅い理由がやっと分かりました!なぜなら、ラップトップからスクリプトを実行し、外部ホスト名からデータベースにアクセスしているからです。スクリプトをサーバーにアップロードし、イントラネット内からデータベースにアクセスすると、はるかに高速になりました。 10,000 レコードの挿入には約 3 ~ 4 秒かかり、100,000 レコードの挿入には約 36 秒かかります。インターネットがないだけで、こんなに違うことになるのですね!
しかし、
executemany は私の場合パフォーマンスを改善しませんでした。
あなたの例では、ストアド プロシージャの利点をまったく活用していないため、ストアド プロシージャをクレジットしません。
ストアド プロシージャの主な利点は次のとおりです。
###編集済み###- ネットワーク交換を節約します
(計算はサーバー側で行われるため)-
UPDATE では操作できないほど複雑なロジックがあり、それをたとえば Python で実行したいとします。
が必要です。行を選択- -> ネットワーク トラフィック [サーバー -> クライアント]
行を更新- -> かなり遅い: Python は解釈されますが、SQLAlchemy のような ORM を使用するとさらに遅くなる可能性があります (オブジェクトはメモリ内に作成する必要があります)
更新された行を送り返す- -> ネットワーク トラフィック [クライアント -> サーバー]
同じ例がストアド プロシージャを使用して実装されたと想像してください。
この種の例では、ストアド プロシージャが実際に違いを生む可能性が高くなります。
この例にはロジックはなく、行を挿入するだけです。 これは I/O バウンドのユースケースです。コンパイルされたプログラムを使用する利点はほとんどありません。 INSERT と同じくらい多くのネットワーク交換が可能になります。 いずれの場合も、行をサーバーに送信する必要があります。 ネットワークトラフィックも増加していません。
あなたの例では、おそらく
一括挿入が最高のパフォーマンスを達成するのに役立ちます。