【发布时间】:2020-02-24 20:08:08
【问题描述】:
假设我们有下一张桌子:
CREATE TABLE test_insert_order (
id INT(11) NOT NULL AUTO_INCREMENT,
parent_id INT(11) NOT NULL,
name VARCHAR(20),
PRIMARY KEY (id)
);
像一些数据
INSERT INTO test_insert_order (parent_id, name) VALUES (1, 'a'),(1, 'b'),(1,'c'),(2,'b'),(2,'d'),(2,'a'),(3,'d'),(3,'a'),(4,'aa'),(5,'bb'),(6,'a'),(3,'a'),(1,'d'),(2,'c');
如果我们这样做
INSERT INTO test_insert_order (parent_id, name) SELECT 7, `name` FROM test_insert_order WHERE parent_id = 2 ORDER BY id;
我们可以假设新的自动生成的 id 将与选择结果中的 id 的顺序相同
SELECT id, 7, `name` FROM test_insert_order WHERE parent_id = 2 ORDER BY id;
所以结果下一个查询 a.name 将始终匹配 b.name
SET @i:=0;set @j:=0;
SELECT a.id, a.parent_id, a.name, a.order_id, b.id, b.parent_id, b.name, b.order_id FROM
(SELECT *, @j:=@j+1 as order_id FROM test_insert_order WHERE parent_id = 2 ORDER BY id) a,
(SELECT *, @i:=@i+1 as order_id FROM test_insert_order WHERE parent_id = 7 ORDER BY id) b
WHERE a.order_id = b.order_id;
我已经对并发胎面进行了一些测试,并且始终是正确的。但我在 MySQL 文档中找不到关于这种情况的任何内容。
更新: 我想这在某些集群解决方案中可能不是真的,因为一些实例具有自己的自动增量值模式,并且一个实例落后并且查询执行在某些情况下分布。但是我没有环境来检查这个。
【问题讨论】:
-
基于this accepted answer,插入的行顺序与选择查询中遇到的行顺序相匹配。
-
@TimBiegeleisen 所以你说的是 ``` INSERT .. SELECT .. ORDER BY...; ``` 等价于 ``` INSERT ... SELECT .... ORDER BY ... LIMIT 0, 1; INSERT ... SELECT .... ORDER BY ... LIMIT 1,1 ; ... 插入 ... 选择 .... ORDER BY ... 限制 n-1,1 ; ``` 你有任何关于 MySQL 文档的注释吗?
-
我不知道文档参考,但我从来不知道还有什么是真实的。
-
@TimBiegeleisen 我只是担心,因为我发现许多堆栈溢出答案表明 order by 对于 INSERT ... SELECT 语句无关紧要,但没有一个与 auto_increment 字段有关。无论如何感谢您的评论。
-
是的,这很重要,但话说回来,你已经在使用
ORDER BY,所以我懒得对此发表评论。
标签: mysql sql-order-by auto-increment bulkinsert