【问题标题】:Should I commit to my database inside the while loop or outside?我应该在 while 循环内部还是外部提交我的数据库?
【发布时间】:2018-03-17 07:18:43
【问题描述】:

我有这样的事情:

# pseudo code
while True:
   result = make_request_for_data(my_http_request)
   query = "INSERT INTO my_table (col1, col2) VALUES (%s, %s);"

   for data in result:
       cursor.execute(query, data)

   connection.commit() # should this be inside while loop or outside?

   if result is None:  # some breaking mechanism
       break

cursor.close()
connection.close()

有性能优势吗?为什么?我会做一些时间安排,但想知道为什么如果是这样的话,一个比另一个更好。

【问题讨论】:

  • 这样会效率低下。更好的方法是将您的数据集分解为一个批量大小,您可以在其中插入 N 条记录,然后提交。您需要了解数据库正在为您做什么。它会创建一个您每次提交的回滚段。它不应该是一个记录;如果记录数很大,则不应为 N。
  • 我建议,在while循环中concat所有的insert命令一起在数据库上执行一次,在数据库操作上,你去数据库的次数会是最贵的
  • @Serjik 澄清一下,您是否建议我连接我的查询,以便查询字符串是多个插入语句,然后运行 ​​cursor.execute 一次?在循环的每次迭代中,result 最多保存 1000 条记录 - 是否存在 1000 条 INSERT 语句?
  • @Petar 然后不管有没有事务,你都应该保留一个计数器,当它达到一定的数字(考虑 100*N)然后提交到数据库。然后您将少执行 100 次 DB 操作。
  • @Petar 这篇文章也应该对你有所帮助stackoverflow.com/questions/2741919/…

标签: python database postgresql performance psycopg2


【解决方案1】:

这取决于,它取决于什么比性能重要得多。问问自己:

整个循环是单个原子业务操作,还是循环的每次迭代都是单个原子业务操作?

也就是说,假设您正在循环超过 10 条记录,并且记录 #5 以某种方式失败。还应该提交 1-4 吗?如果是这样,请在循环内提​​交。如果没有,请在循环外提交。

更改提交数据的位置确实会影响性能,但更重要的是它会影响正在实施的系统的逻辑。

【讨论】:

  • result 将在每次迭代中最多保存 1000 条记录。如果一个失败,其他的仍然有效。所以我猜每次迭代都是原子的。
  • @Petar:如果每次迭代都是原子的,那么听起来除了在循环内提​​交之外别无选择。性能可能会受到影响,但出于实现预期逻辑的目的。在这一点上提高性能将涉及研究一些更快的提交机制,例如提交到消息队列而不是数据库,并让单独的进程读取队列并提交到数据库。但这当然取决于这个过程的最终结果是什么,以及为什么性能是一个问题。例如,如果这需要快速返回 UI。
  • 这与 UI 无关,因此不必非常快。我目前正在使用它来将一些数据推送到测试数据库中。我想如果我想从现在开始提高性能,我应该看看批量插入(?)
  • @Petar:批量插入可能会更快,是的。它会将整个操作变成一个单一的原子操作。从那个描述来看,这听起来像是一个可以接受的变化?如果是这样,那么如果性能确实是一个痛点,那可能值得一看。
猜你喜欢
  • 2021-01-05
  • 1970-01-01
  • 2014-03-18
  • 1970-01-01
  • 2017-11-14
  • 2010-09-13
  • 2019-09-23
  • 2014-03-24
  • 1970-01-01
相关资源
最近更新 更多