我正在编写一个 Django-ORM 增强功能,它尝试缓存模型并将模型保存推迟到事务结束。一切都差不多完成了,但是我在 SQL 语法中遇到了一个意想不到的困难。

我不是一个 DBA,但据我所知,对于许多小查询,数据库并不能真正有效地工作。几个更大的查询要好得多。例如,最好使用大批量插入(比如一次 100 行)而不是 100 个单行插入。

现在,据我所知,SQL 并没有真正提供任何语句来对表执行批量更新。这个术语似乎令人困惑,所以我将解释我的意思。我有一组任意数据,每个条目描述表中的一行。我想更新表中的某些行,每行都使用来自数组中相应条目的数据。这个想法与批量插入非常相似。

例如:我的表可能有两列 "id""some_col" 。现在,描述批量更新数据的数组包含三个条目 (1, 'first updated')(2, 'second updated')(3, 'third updated') 。在更新之前,该表包含以下行: (1, 'first')(2, 'second')(3, 'third')

我遇到了这个帖子:

Why are batch inserts/updates faster? How do batch updates work?

这似乎做我想要的,但是我无法真正弄清楚最后的语法。

我也可以删除所有需要更新的行并使用批量插入重新插入它们,但是我发现很难相信这实际上会表现得更好。

我使用 PostgreSQL 8.4,所以这里也可以使用一些存储过程。然而,当我计划最终开源该项目时,任何在不同 RDBMS 上做同样事情的更便携的想法或方法都是最受欢迎的。

跟进问题: 如何执行批量“插入或更新”/“更新插入”语句?

测试结果

我已经在 4 个不同的表上执行了 100 次 10 次插入操作(总共 1000 次插入)。我在带有 PostgreSQL 8.4 后端的 Django 1.3 上进行了测试。

这些是结果:

  • 通过 Django ORM 完成的所有操作 - 每次通过 ~2.45 秒 ,
  • 相同的操作,但没有 Django ORM 完成 - 每次传递 ~1.48 秒 ,
  • 只做插入操作,不向数据库查询序列值 ~0.72 秒 ,
  • 仅插入操作,分 10 个块执行(共 100 个块) ~0.19 秒 , 0x291912421334111
  • 仅插入操作,一大块执行块 ~0.13 秒
  • 仅插入操作,每块约 250 条语句, ~0.12 秒

  • 结论:在单个 connection.execute() 中执行尽可能多的操作。 Django 本身引入了大量开销。

    免责声明:除了默认主键索引之外,我没有引入任何索引,因此插入操作可能会运行得更快。

    最佳答案

    我使用了 3 种策略进行批处理事务性工作:

  • 动态生成SQL语句,用分号连接,一键提交。我以这种方式完成了多达 100 次插入,而且效率很高(针对 Postgres 完成)。
  • JDBC 具有内置的批处理功能(如果已配置)。如果生成事务,则可以刷新 JDBC 语句,以便它们一次性完成事务。这种策略需要较少的数据库调用,因为语句都是在一批中执行的。
  • Hibernate 也支持前面示例中的 JDBC 批处理,但在这种情况下,您对 Hibernate flush() 而非底层 JDBC 连接执行 Session 方法。它完成与 JDBC 批处理相同的事情。

  • 顺便说一下,Hibernate 还支持集合获取中的批处理策略。如果使用 @BatchSize 注释集合,则在获取关联时,Hibernate 将使用 IN 而不是 = ,从而减少了 0x25181214143 加载语句。

    关于sql - PostgreSQL 中的批量/批量更新/更新插入,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7019831/

    10-16 10:36
    查看更多