通过select
语句插入Postgres时,是否保证按照select语句返回的顺序插入行?
也就是说,给定一个表bar
(其中id
为SERIAL PRIMARY KEY
,name
为TEXT
):
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之前有效地评估了查询表达式”,但它没有明确说明任何有关排序的内容。标准是否有目的地模糊(也许允许并行插入?)和排序是一个实现细节?
答案 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
节点。