【问题标题】:Do transaction in Django make things faster在 Django 中做事务让事情变得更快
【发布时间】:2015-09-30 00:54:04
【问题描述】:

我有一个 Django 应用程序。

这个 Django 应用程序对 Twitter 进行 api 调用并获取我最近的 100 条推文。我需要将推文插入数据库。

我有一种方法可以对所有 100 条推文采取行动。这个方法有一个 for 循环,我从每个 Tweet 中创建一个模型实例,并分别在每个实例上调用 instance.save()。

我发现事情变慢了,并认为事务可能会使事情变得更快。

所以在方法之外我添加了@method_decorator(transaction.atomic)。我仍然有一个 for 循环,在其中创建模型实例并执行 instance.save() 但现在该方法用 transaction.atomic 装饰。

  1. transaction.atomic 是否应该让我更快地插入数据库?
  2. 每个 instance.save() 调用是否仍会发出数据库调用?
  3. 如果它能让事情变得更快,那又如何?

【问题讨论】:

    标签: django database transactions


    【解决方案1】:
    1. 没有。数据库事务的目的是确保数据的完整性。请参阅Wikipedia 了解更多信息。

    2. 是的。使用事务不会影响这一点。

    3. 没有。

    应该让您的代码更快的是在一个查询中一次提交所有新记录,而不是一次一个。查看 Django 的bulk_create。总是很难预测性能,但我怀疑这会显着改善情况。

    【讨论】:

      【解决方案2】:

      在原子事务中,一系列数据库操作要么全部发生,要么什么都不发生

      将方法装饰为atomic 将保证该方法中代码块在数据库上的原子性。如果该方法成功完成,则将更改提交到数据库。如果出现异常,则回滚更改。

      1.根据您的用例,事务不会使您的代码更快。 事实上,它只会保证所有tweets 将被保存到数据库中,或者tweets 不会被保存在案例中的一个例外。

      2。是的,每个instance.save() 调用都是一个数据库调用。因此,每次将有 100 个数据库调用。

      3.同样,事务不会使您的用例更快。

      那么如何让事情变得更快?

      您可以使用 Django 的 bulk_create 在单个查询中创建所有 tweets

      Tweet.objects.bulk_create([tweet1, tweet2, ...., tweet100]) # single query
      

      这仅在 1 个查询中以有效的方式将 tweet 对象列表插入数据库。

      【讨论】:

      • "事务不会让你的代码变得更快。" ——在实践中,这通常是不正确的。简而言之,打开和关闭单笔交易比打开和关闭 100 笔交易要少得多。根据您的后端和存储引擎,这可能涉及磁盘 I/O,并且它可能成为主要瓶颈。 bulk_create() 仍然是您提高性能的首选,一次可以处理 100 个项目,但不要仅仅将事务视为加快代码速度的一种手段。 (并测量它,总是测量它。)
      • 是的,在这方面同意你的看法。稍微修改了 ans 以不概括它。是的,在这两种情况下测量时间会给出更好的画面。
      • 请注意,新的 django 版本 >2 也支持 bulk_update。这在以前是不可能的,然后通常会导致为每个对象调用 save()。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-22
      • 2012-11-29
      • 1970-01-01
      • 2013-11-10
      • 1970-01-01
      • 2012-06-05
      • 1970-01-01
      相关资源
      最近更新 更多