Postgres使用SELECT排序INSERT INTO

时间:2018-06-12 04:09:57

标签: sql postgresql

通过select语句插入Postgres时,是否保证按照select语句返回的顺序插入行?

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

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

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

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

这似乎是这种情况,但我想确认它不是一个实现细节,可能无法用更大的选择。

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

2 个答案:

答案 0 :(得分:2)

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

Postgres,显式为9.6,将按照返回结果集的顺序进行逻辑插入。

行为在此提​​交中明确编纂:https://github.com/postgres/postgres/commit/9118d03a8cca3d97327c56bf89a72e328e454e63

来自提交说明:

  

例如,在SELECT x中,nextval('seq')FROM选项卡ORDER BY x LIMIT   10;可能需要对nextval()值进行排序   与x相同,而nextval()的运行次数不超过10次。

     

在过去,Postgres在这方面不一致:你会得到的   如果通过索引扫描执行排序,则需要的行为,   但不是如果必须通过明确的排序步骤来完成的。

TL;博士;插入顺序是一个实现细节,但在Postgres 9.6及更高版本中有目的地编码以匹配一个人的直觉。在9.6之前,没有任何保证。

答案 1 :(得分:1)

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

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