querysetで複数updateしたいならbulk_updateの方が早いから使うべき
今回はquerysetで複数のデータに対してupdateしたいならbulk_updateの方が早いから使うべきということについてお話ししていきたいと思います。
querysetで複数updateしたいならbulk_updateの方が早いから使うべき
querysetで複数のデータに対してupdateしたいならbulk_updateの方がパフォーマンスが良いためbulk_updateを使うべきです。
今回はupdateとbulk_updateでどれくらい実行時間が異なるのか調査してみました。
調査に当たって以下のソースを準備しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
from book.models import Book import time def create_data(): # start = time.time() book_objects = [] for i in range(10000): book_objects.append(Book(title='title' + str(i+1))) Book.objects.bulk_create(book_objects) # process_time = time.time() - start # print(process_time) def update_test(): bookAll = Book.objects.all() start = time.time() for i, book in enumerate(bookAll): book.title = 'changed' + str(i+1) book.save() process_time = time.time() - start print(process_time) def bulk_update_test(): bookAll = Book.objects.all() start = time.time() book_objects = [] for i, book in enumerate(bookAll): book.title = 'changed' + str(i+1) book_objects.append(book) Book.objects.bulk_update(book_objects, ['title']) process_time = time.time() - start print(process_time) |
create_data()は下準備のための関数です。
Bookモデルを使ってパフォーマンスの調査をしますが、create_data()でBookオブジェクトを1万個生成いたします。
update_test()はquerysetのupdate()をする関数です。
update()を1万個のBookオブジェクトに対して片っ端から行います。
また、timeモジュールを使ってupdate_test()の実行時間を計測します。
bulk_update_test()はquerysetのbulk_update()をする関数です。
update_test()と同じように1万個のBookオブジェクトに対して処理を行い、実行時間を計測します。
create_data()を使って1万個のBookオブジェクトを生成したのち、update_test()を3回行ってみましょう。
なお、一回処理を行うごとにオブジェクトを一旦すべてdeleteして再度create_data()を使って1万個のBookオブジェクトを生成し直しております。
update_test()を3回実行した結果はこちらです。
1 2 |
>>> update_test() 16.59220004081726 |
1 2 |
>>> update_test() 15.765231847763062 |
1 2 |
>>> update_test() 16.891082048416138 |
上記の結果より、update_test()の実行時間は16秒前後という結果になりました。
一方、bulk_update_test()を3回実行してみます。
update_test()と同じように1万個のBookオブジェクトに対して処理を行い、一回処理を行うごとにオブジェクトを一旦すべてdeleteして再度create_data()を使って1万個のBookオブジェクトを生成し直すということをします。
bulk_update_test()を3回実行した結果は次の通りです。
1 2 |
>>> bulk_update_test() 2.0309951305389404 |
1 2 |
>>> bulk_update_test() 1.821319341659546 |
1 2 |
>>> bulk_update_test() 1.8023560047149658 |
bulk_update_test()の実行時間は2秒程度です。
update()よりもbulk_update()の方が断然早いということが分かりますね。
querysetで複数のオブジェクトに対して更新したいときはupdate()よりもbulk_update()を使用するようにしましょう。
終わりに
今回はquerysetで複数updateしたいならbulk_updateの方が早いから使うべきということについてお話しいたしました。
PythonやPythonを使ったライブラリやフレームワークのパフォーマンスの調査に興味があり、様々なコーディング方法の違いによる最適化の調査を行っております。
リストにまとめてあるので、よろしければ覗いてみてください。
Pythonとそのライブラリやフレームワークのパフォーマンス調査結果リスト
ディスカッション
コメント一覧
まだ、コメントがありません