【问题标题】:Postgres INSERT INTO with SELECT ordering带有 SELECT 排序的 Postgres INSERT INTO
【发布时间】:2018-06-12 04:09:56
【问题描述】:

当通过select 语句插入 Postgres 时,是否保证插入的行与 select 语句返回的顺序相同?

也就是说,给定一个表bar(其中idSERIAL PRIMARY KEYnameTEXT):

id | name
---+-----
 0 | A
 1 | B
 2 | C

如果我INSERT INTO foo (name) SELECT name FROM bar ORDER BY id DESC 将保证foo 有另一个表,foo(空且具有相同的架构):

id | name
---+-----
 0 | C
 1 | B
 2 | A

似乎是这样,但我想确认它不是一个可能不适用于较大选择的实现细节。

我通读了SQL-92 standard 中的第 13.8 节,一般规则 #3 声称“在将任何行插入 B 之前有效地评估了查询表达式”,但它没有明确说明有关排序的任何内容。标准是否有意模糊(也许允许并行插入?)并且排序是实现细节?

【问题讨论】:

  • 这个DBA Stack Exchange article 似乎拒绝了。您不应该依赖任何内部订单。
  • @marc_s 这里有一个 ORDER BY,只是一个问题 INSERT 是否按这个顺序处理结果
  • @marc_s 这不是无关紧要的。有一个用于创建 ID 的序列。这很大程度上是插入顺序和副作用的问题。不是查询时的结果。触发器也是如此,它们是否按照 SELECT 查询返回行的顺序运行。
  • 这是一个有趣的问题。虽然 MySQL 在他们的文档中声明 ORDER BY 确实很重要,而且对于 SQL Server 也有微软人员证实了这一点,但我在 Internet 上找不到任何关于 PostgreSQL(或 Oracle)的信息。我认为这应该在文档中明确说明。对于 PostgreSQL,postgresql.org/docs/current/static/sql-insert.html 中有一个链接可引导您进入一个表单,您应该可以在该表单中要求他们在其文档中的 INSERT SELECT 中包含对 ORDER BY 的解释。
  • 插入保证“模仿”选择的顺序。例如,与包含使用delete 删除的行的表相比,新创建的表中的“插入顺序”可能不同,而包含使用truncate 和另一个删除的行的表的另一个“顺序”可能不同如果只删除了一半的行,则为“order”。对于SELECT 语句,获得保证 订单的only(实际上:only)方法是使用order by。没有其他选择。

标签: sql postgresql


【解决方案1】:

我在 Postgres 邮件列表上询问过,他们在澄清方面很有帮助。事实证明,这是一个特定于数据库的答案,所以如果您正在阅读本文并使用不同的数据库,答案可能会不一样。

从 9.6 开始,Postgres 将按照返回结果集的顺序进行逻辑插入。

此提交中明确规定了该行为:https://github.com/postgres/postgres/commit/9118d03a8cca3d97327c56bf89a72e328e454e63

来自提交描述:

例如,在 SELECT x 中,nextval('seq') FROM tab ORDER BY x LIMIT 10个;可能需要将 nextval() 值排序为 与 x 相同,并且 nextval() 运行次数不超过 10 次。

过去,Postgres 在这方面是不一致的:你会得到 如果排序是通过 indexscan 执行的,那么理想的行为, 但如果它必须通过显式排序步骤完成。

tl;博士;插入顺序是一个实现细节,但在 Postgres 9.6 及更高版本中有意编码以符合直觉。在 9.6 之前,没有任何保证。

【讨论】:

    【解决方案2】:

    新表中的行将按照ORDER BY 子句指定的顺序插入,因此从该序列生成的id 将反映此顺序。

    要验证这一点,请查看执行计划,您应该能够在Insert 之前看到Sort 节点。

    【讨论】:

    • 感谢您的回复,但请注意在我的示例查询中 is 有一个 ORDER BY 子句。
    • 最后一段回答了你的问题。其余的应该解决您对 SQL 标准的担忧。
    • 我发现最后一段有点模棱两可。项目是否会按照从select 查询返回的顺序插入?为什么非空表会发生这种变化?
    • @LaurenzAlbe 我认为 OP 只是想知道 ORDER BY 是否与选择一起使用,自动增量 ID 本身是否对应于相应选择会生成的插入顺序?
    • 我已经修改了答案,现在应该是你需要的了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 2011-10-25
    • 2015-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多